├── .gitattributes
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── config.yml
│ └── feature_request.md
├── dependabot.yml
├── stale.yml
└── workflows
│ ├── merge-dependabot.yml
│ └── on-push-do-doco.yml
├── .gitignore
├── code_of_conduct.md
├── files
├── archive
│ ├── empty.7z
│ ├── empty.7zip
│ ├── empty.bz2
│ ├── empty.bzip2
│ ├── empty.gz
│ ├── empty.gzip
│ ├── empty.nupkg
│ ├── empty.tar
│ ├── empty.xz
│ └── empty.zip
├── document
│ ├── empty.docx
│ ├── empty.odt
│ ├── empty.pdf
│ └── empty.rtf
├── image
│ ├── empty.avif
│ ├── empty.bmp
│ ├── empty.dds
│ ├── empty.dib
│ ├── empty.emf
│ ├── empty.exif
│ ├── empty.gif
│ ├── empty.heic
│ ├── empty.heif
│ ├── empty.ico
│ ├── empty.j2c
│ ├── empty.jfif
│ ├── empty.jp2
│ ├── empty.jpc
│ ├── empty.jpe
│ ├── empty.jpeg
│ ├── empty.jpg
│ ├── empty.jxr
│ ├── empty.pbm
│ ├── empty.pcx
│ ├── empty.pgm
│ ├── empty.png
│ ├── empty.ppm
│ ├── empty.rle
│ ├── empty.tga
│ ├── empty.tif
│ ├── empty.tiff
│ ├── empty.wdp
│ ├── empty.webp
│ └── empty.wmp
├── sheet
│ ├── empty.ods
│ └── empty.xlsx
└── slide
│ ├── empty.odp
│ └── empty.pptx
├── index
├── empty.7z
├── empty.7zip
├── empty.avif
├── empty.bmp
├── empty.bz2
├── empty.bzip2
├── empty.dds
├── empty.dib
├── empty.docx
├── empty.emf
├── empty.exif
├── empty.gif
├── empty.gz
├── empty.gzip
├── empty.heic
├── empty.heif
├── empty.ico
├── empty.j2c
├── empty.jfif
├── empty.jp2
├── empty.jpc
├── empty.jpe
├── empty.jpeg
├── empty.jpg
├── empty.jxr
├── empty.odp
├── empty.ods
├── empty.odt
├── empty.pbm
├── empty.pcx
├── empty.pdf
├── empty.pgm
├── empty.png
├── empty.ppm
├── empty.pptx
├── empty.rle
├── empty.rtf
├── empty.tar
├── empty.tga
├── empty.tif
├── empty.tiff
├── empty.wdp
├── empty.webp
├── empty.wmp
├── empty.xlsx
├── empty.xz
└── empty.zip
├── license.txt
├── readme.md
└── src
├── .editorconfig
├── Directory.Build.props
├── Directory.Packages.props
├── EmptyFiles.Tool
├── AssemblyInfo.cs
├── EmptyFiles.Tool.csproj
└── Program.cs
├── EmptyFiles.sln
├── EmptyFiles.sln.DotSettings
├── EmptyFiles.targets
├── EmptyFiles
├── AllFiles.cs
├── AssemblyLocation.cs
├── Category.cs
├── ClsCompliant.cs
├── ContentTypes.cs
├── EmptyFile.cs
├── EmptyFiles.csproj
├── FileExtensions.cs
├── GlobalUsings.cs
├── Guard.cs
└── IsTextFile.cs
├── Shared.sln.DotSettings
├── Tests
├── ContentTypesTests.cs
├── ExtensionsTests.cs
├── GlobalUsings.cs
├── ImmutableVersionTests.cs
├── IndexWriter.cs
├── Size.cs
├── SolutionDirectoryFinder.cs
├── Tests.cs
└── Tests.csproj
├── appveyor.yml
├── extensions.include.md
├── global.json
├── icon.png
├── key.snk
├── mdsnippets.json
└── nuget.config
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text
2 | *.snk binary
3 | *.png binary
4 |
5 | /files/** binary
6 | /index/** binary
7 |
8 | *.verified.txt text eol=lf working-tree-encoding=UTF-8
9 | *.verified.xml text eol=lf working-tree-encoding=UTF-8
10 | *.verified.json text eol=lf working-tree-encoding=UTF-8
11 |
12 | .editorconfig text eol=lf working-tree-encoding=UTF-8
13 | Shared.sln.DotSettings text eol=lf working-tree-encoding=UTF-8
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: VerifyTests
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug fix
3 | about: Create a bug fix to help us improve
4 | ---
5 |
6 | Note: New issues raised, where it is clear the submitter has not read the issue template, are likely to be closed with "please read the issue template". Please don't take offense at this. It is simply a time management decision. If someone raises an issue, and can't be bothered to spend the time to read the issue template, then the project maintainers should not be expected to spend the time to read the submitted issue. Often too much time is spent going back and forth in issue comments asking for information that is outlined in the issue template.
7 |
8 |
9 | #### Preamble
10 |
11 | General questions may be better placed [StackOveflow](https://stackoverflow.com/).
12 |
13 | Where relevant, ensure you are using the current stable versions on your development stack. For example:
14 |
15 | * Visual Studio
16 | * [.NET SDK or .NET Core SDK](https://www.microsoft.com/net/download)
17 | * Any related NuGet packages
18 |
19 | Any code or stack traces must be properly formatted with [GitHub markdown](https://guides.github.com/features/mastering-markdown/).
20 |
21 |
22 | #### Describe the bug
23 |
24 | A clear and concise description of what the bug is. Include any relevant version information.
25 |
26 | A clear and concise description of what you expected to happen.
27 |
28 | Add any other context about the problem here.
29 |
30 |
31 | #### Minimal Repro
32 |
33 | Ensure you have replicated the bug in a minimal solution with the fewest moving parts. Often this will help point to the true cause of the problem. Upload this repro as part of the issue, preferably a public GitHub repository or a downloadable zip. The repro will allow the maintainers of this project to smoke test the any fix.
34 |
35 | #### Submit a PR that fixes the bug
36 |
37 | Submit a [Pull Request (PR)](https://help.github.com/articles/about-pull-requests/) that fixes the bug. Include in this PR a test that verifies the fix. If you were not able to fix the bug, a PR that illustrates your partial progress will suffice.
38 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: How to raise feature requests
4 | ---
5 |
6 |
7 | Note: New issues raised, where it is clear the submitter has not read the issue template, are likely to be closed with "please read the issue template". Please don't take offense at this. It is simply a time management decision. If someone raises an issue, and can't be bothered to spend the time to read the issue template, then the project maintainers should not be expected to spend the time to read the submitted issue. Often too much time is spent going back and forth in issue comments asking for information that is outlined in the issue template.
8 |
9 | If you are certain the feature will be accepted, it is better to raise a [Pull Request (PR)](https://help.github.com/articles/about-pull-requests/).
10 |
11 | If you are uncertain if the feature will be accepted, outline the proposal below to confirm it is viable, prior to raising a PR that implements the feature.
12 |
13 | Note that even if the feature is a good idea and viable, it may not be accepted since the ongoing effort in maintaining the feature may outweigh the benefit it delivers.
14 |
15 |
16 | #### Is the feature request related to a problem
17 |
18 | A clear and concise description of what the problem is.
19 |
20 |
21 | #### Describe the solution
22 |
23 | A clear and concise proposal of how you intend to implement the feature.
24 |
25 |
26 | #### Describe alternatives considered
27 |
28 | A clear and concise description of any alternative solutions or features you've considered.
29 |
30 |
31 | #### Additional context
32 |
33 | Add any other context about the feature request here.
34 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: nuget
4 | directory: "/src"
5 | schedule:
6 | interval: daily
7 | open-pull-requests-limit: 10
8 |
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | daysUntilStale: 7
3 | # Number of days of inactivity before a stale issue is closed
4 | daysUntilClose: 7
5 | # Set to true to ignore issues in a milestone (defaults to false)
6 | exemptMilestones: true
7 | # Comment to post when marking an issue as stale. Set to `false` to disable
8 | markComment: >
9 | This issue has been automatically marked as stale because it has not had
10 | recent activity. It will be closed if no further activity occurs. Thank you
11 | for your contributions.
12 | # Comment to post when closing a stale issue. Set to `false` to disable
13 | closeComment: false
14 | # Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
15 | pulls:
16 | daysUntilStale: 30
17 | exemptLabels:
18 | - Question
19 | - Bug
20 | - Feature
21 | - Improvement
--------------------------------------------------------------------------------
/.github/workflows/merge-dependabot.yml:
--------------------------------------------------------------------------------
1 | name: merge-dependabot
2 | on:
3 | pull_request:
4 | jobs:
5 | automerge:
6 | runs-on: ubuntu-latest
7 | if: github.actor == 'dependabot[bot]'
8 | steps:
9 | - name: Dependabot Auto Merge
10 | uses: ahmadnassri/action-dependabot-auto-merge@v2.6.6
11 | with:
12 | target: minor
13 | github-token: ${{ secrets.dependabot }}
14 | command: squash and merge
--------------------------------------------------------------------------------
/.github/workflows/on-push-do-doco.yml:
--------------------------------------------------------------------------------
1 | name: on-push-do-doco
2 | on:
3 | push:
4 | jobs:
5 | release:
6 | runs-on: windows-latest
7 | steps:
8 | - uses: actions/checkout@v4
9 | - name: Run MarkdownSnippets
10 | run: |
11 | dotnet tool install --global MarkdownSnippets.Tool
12 | mdsnippets ${GITHUB_WORKSPACE}
13 | shell: bash
14 | - name: Push changes
15 | run: |
16 | git config --local user.email "action@github.com"
17 | git config --local user.name "GitHub Action"
18 | git commit -m "Doco changes" -a || echo "nothing to commit"
19 | remote="https://${GITHUB_ACTOR}:${{secrets.GITHUB_TOKEN}}@github.com/${GITHUB_REPOSITORY}.git"
20 | branch="${GITHUB_REF:11}"
21 | git push "${remote}" ${branch} || echo "nothing to push"
22 | shell: bash
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.suo
2 | *.user
3 | bin/
4 | obj/
5 | .vs/
6 | *.DotSettings.user
7 | .idea/
8 | *.received.*
9 | nugets/
--------------------------------------------------------------------------------
/code_of_conduct.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at simon.cropp@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/files/archive/empty.7z:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/archive/empty.7z
--------------------------------------------------------------------------------
/files/archive/empty.7zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/archive/empty.7zip
--------------------------------------------------------------------------------
/files/archive/empty.bz2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/archive/empty.bz2
--------------------------------------------------------------------------------
/files/archive/empty.bzip2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/archive/empty.bzip2
--------------------------------------------------------------------------------
/files/archive/empty.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/archive/empty.gz
--------------------------------------------------------------------------------
/files/archive/empty.gzip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/archive/empty.gzip
--------------------------------------------------------------------------------
/files/archive/empty.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/archive/empty.nupkg
--------------------------------------------------------------------------------
/files/archive/empty.tar:
--------------------------------------------------------------------------------
1 | empty 0100777 0000000 0000000 00000000000 13602262730 007064 0 ustar 00
--------------------------------------------------------------------------------
/files/archive/empty.xz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/archive/empty.xz
--------------------------------------------------------------------------------
/files/archive/empty.zip:
--------------------------------------------------------------------------------
1 | PK
--------------------------------------------------------------------------------
/files/document/empty.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/document/empty.docx
--------------------------------------------------------------------------------
/files/document/empty.odt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/document/empty.odt
--------------------------------------------------------------------------------
/files/document/empty.pdf:
--------------------------------------------------------------------------------
1 | %PDF-1.0
2 | 1 0 obj<>endobj 2 0 obj<>endobj 3 0 obj<>endobj
3 | xref
4 | 0 4
5 | 0000000000 65535 f
6 | 0000000010 00000 n
7 | 0000000053 00000 n
8 | 0000000102 00000 n
9 | trailer<>
10 | startxref
11 | 149
12 | %EOF
--------------------------------------------------------------------------------
/files/document/empty.rtf:
--------------------------------------------------------------------------------
1 | {\rtf}
--------------------------------------------------------------------------------
/files/image/empty.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.avif
--------------------------------------------------------------------------------
/files/image/empty.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.bmp
--------------------------------------------------------------------------------
/files/image/empty.dds:
--------------------------------------------------------------------------------
1 | DDS |
2 | DXT1
--------------------------------------------------------------------------------
/files/image/empty.dib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.dib
--------------------------------------------------------------------------------
/files/image/empty.emf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.emf
--------------------------------------------------------------------------------
/files/image/empty.exif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.exif
--------------------------------------------------------------------------------
/files/image/empty.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.gif
--------------------------------------------------------------------------------
/files/image/empty.heic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.heic
--------------------------------------------------------------------------------
/files/image/empty.heif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.heif
--------------------------------------------------------------------------------
/files/image/empty.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.ico
--------------------------------------------------------------------------------
/files/image/empty.j2c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.j2c
--------------------------------------------------------------------------------
/files/image/empty.jfif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.jfif
--------------------------------------------------------------------------------
/files/image/empty.jp2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.jp2
--------------------------------------------------------------------------------
/files/image/empty.jpc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.jpc
--------------------------------------------------------------------------------
/files/image/empty.jpe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.jpe
--------------------------------------------------------------------------------
/files/image/empty.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.jpeg
--------------------------------------------------------------------------------
/files/image/empty.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.jpg
--------------------------------------------------------------------------------
/files/image/empty.jxr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.jxr
--------------------------------------------------------------------------------
/files/image/empty.pbm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.pbm
--------------------------------------------------------------------------------
/files/image/empty.pcx:
--------------------------------------------------------------------------------
1 |
2 | ` `
--------------------------------------------------------------------------------
/files/image/empty.pgm:
--------------------------------------------------------------------------------
1 | P5
2 | 1 1
3 | 255
4 |
--------------------------------------------------------------------------------
/files/image/empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.png
--------------------------------------------------------------------------------
/files/image/empty.ppm:
--------------------------------------------------------------------------------
1 | P6
2 | 1 1
3 | 255
4 |
--------------------------------------------------------------------------------
/files/image/empty.rle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.rle
--------------------------------------------------------------------------------
/files/image/empty.tga:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.tga
--------------------------------------------------------------------------------
/files/image/empty.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.tif
--------------------------------------------------------------------------------
/files/image/empty.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.tiff
--------------------------------------------------------------------------------
/files/image/empty.wdp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.wdp
--------------------------------------------------------------------------------
/files/image/empty.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.webp
--------------------------------------------------------------------------------
/files/image/empty.wmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/image/empty.wmp
--------------------------------------------------------------------------------
/files/sheet/empty.ods:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/sheet/empty.ods
--------------------------------------------------------------------------------
/files/sheet/empty.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/sheet/empty.xlsx
--------------------------------------------------------------------------------
/files/slide/empty.odp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/slide/empty.odp
--------------------------------------------------------------------------------
/files/slide/empty.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/files/slide/empty.pptx
--------------------------------------------------------------------------------
/index/empty.7z:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.7z
--------------------------------------------------------------------------------
/index/empty.7zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.7zip
--------------------------------------------------------------------------------
/index/empty.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.avif
--------------------------------------------------------------------------------
/index/empty.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.bmp
--------------------------------------------------------------------------------
/index/empty.bz2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.bz2
--------------------------------------------------------------------------------
/index/empty.bzip2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.bzip2
--------------------------------------------------------------------------------
/index/empty.dds:
--------------------------------------------------------------------------------
1 | DDS |
2 | DXT1
--------------------------------------------------------------------------------
/index/empty.dib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.dib
--------------------------------------------------------------------------------
/index/empty.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.docx
--------------------------------------------------------------------------------
/index/empty.emf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.emf
--------------------------------------------------------------------------------
/index/empty.exif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.exif
--------------------------------------------------------------------------------
/index/empty.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.gif
--------------------------------------------------------------------------------
/index/empty.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.gz
--------------------------------------------------------------------------------
/index/empty.gzip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.gzip
--------------------------------------------------------------------------------
/index/empty.heic:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.heic
--------------------------------------------------------------------------------
/index/empty.heif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.heif
--------------------------------------------------------------------------------
/index/empty.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.ico
--------------------------------------------------------------------------------
/index/empty.j2c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.j2c
--------------------------------------------------------------------------------
/index/empty.jfif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.jfif
--------------------------------------------------------------------------------
/index/empty.jp2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.jp2
--------------------------------------------------------------------------------
/index/empty.jpc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.jpc
--------------------------------------------------------------------------------
/index/empty.jpe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.jpe
--------------------------------------------------------------------------------
/index/empty.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.jpeg
--------------------------------------------------------------------------------
/index/empty.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.jpg
--------------------------------------------------------------------------------
/index/empty.jxr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.jxr
--------------------------------------------------------------------------------
/index/empty.odp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.odp
--------------------------------------------------------------------------------
/index/empty.ods:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.ods
--------------------------------------------------------------------------------
/index/empty.odt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.odt
--------------------------------------------------------------------------------
/index/empty.pbm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.pbm
--------------------------------------------------------------------------------
/index/empty.pcx:
--------------------------------------------------------------------------------
1 |
2 | ` `
--------------------------------------------------------------------------------
/index/empty.pdf:
--------------------------------------------------------------------------------
1 | %PDF-1.0
2 | 1 0 obj<>endobj 2 0 obj<>endobj 3 0 obj<>endobj
3 | xref
4 | 0 4
5 | 0000000000 65535 f
6 | 0000000010 00000 n
7 | 0000000053 00000 n
8 | 0000000102 00000 n
9 | trailer<>
10 | startxref
11 | 149
12 | %EOF
--------------------------------------------------------------------------------
/index/empty.pgm:
--------------------------------------------------------------------------------
1 | P5
2 | 1 1
3 | 255
4 |
--------------------------------------------------------------------------------
/index/empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.png
--------------------------------------------------------------------------------
/index/empty.ppm:
--------------------------------------------------------------------------------
1 | P6
2 | 1 1
3 | 255
4 |
--------------------------------------------------------------------------------
/index/empty.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.pptx
--------------------------------------------------------------------------------
/index/empty.rle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.rle
--------------------------------------------------------------------------------
/index/empty.rtf:
--------------------------------------------------------------------------------
1 | {\rtf}
--------------------------------------------------------------------------------
/index/empty.tar:
--------------------------------------------------------------------------------
1 | empty 0100777 0000000 0000000 00000000000 13602262730 007064 0 ustar 00
--------------------------------------------------------------------------------
/index/empty.tga:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.tga
--------------------------------------------------------------------------------
/index/empty.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.tif
--------------------------------------------------------------------------------
/index/empty.tiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.tiff
--------------------------------------------------------------------------------
/index/empty.wdp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.wdp
--------------------------------------------------------------------------------
/index/empty.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.webp
--------------------------------------------------------------------------------
/index/empty.wmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.wmp
--------------------------------------------------------------------------------
/index/empty.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.xlsx
--------------------------------------------------------------------------------
/index/empty.xz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/index/empty.xz
--------------------------------------------------------------------------------
/index/empty.zip:
--------------------------------------------------------------------------------
1 | PK
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Simon Cropp
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | #
EmptyFiles
2 |
3 | [](https://github.com/orgs/VerifyTests/discussions)
4 | [](https://ci.appveyor.com/project/SimonCropp/EmptyFiles)
5 | [](https://www.nuget.org/packages/EmptyFiles/)
6 | [](https://www.nuget.org/packages/EmptyFiles.Tool/)
7 |
8 | A collection of minimal binary files.
9 |
10 | **See [Milestones](../../milestones?state=closed) for release notes.**
11 |
12 |
13 | ### Powered by
14 |
15 | [](https://jb.gg/OpenSourceSupport)
16 |
17 |
18 | ## NuGet package
19 |
20 | * https://nuget.org/packages/EmptyFiles/
21 | * https://nuget.org/packages/EmptyFiles.Tool/
22 |
23 |
24 | ## Files
25 |
26 | All files: https://github.com/VerifyTests/EmptyFiles/tree/main/files
27 |
28 |
29 |
30 | ### Archive
31 |
32 | * .7z (32 bytes)
33 | * .7zip (32 bytes)
34 | * .bz2 (14 bytes)
35 | * .bzip2 (14 bytes)
36 | * .gz (29 bytes)
37 | * .gzip (29 bytes)
38 | * .tar (1.5 KB)
39 | * .xz (32 bytes)
40 | * .zip (22 bytes)
41 |
42 | ### Document
43 |
44 | * .docx (1.9 KB)
45 | * .odt (2.2 KB)
46 | * .pdf (280 bytes)
47 | * .rtf (6 bytes)
48 |
49 | ### Image
50 |
51 | * .avif (298 bytes)
52 | * .bmp (58 bytes)
53 | * .dds (136 bytes)
54 | * .dib (58 bytes)
55 | * .emf (620 bytes)
56 | * .exif (734 bytes)
57 | * .gif (799 bytes)
58 | * .heic (3.2 KB)
59 | * .heif (209 bytes)
60 | * .ico (70 bytes)
61 | * .j2c (270 bytes)
62 | * .jfif (734 bytes)
63 | * .jp2 (354 bytes)
64 | * .jpc (270 bytes)
65 | * .jpe (734 bytes)
66 | * .jpeg (734 bytes)
67 | * .jpg (734 bytes)
68 | * .jxr (300 bytes)
69 | * .pbm (8 bytes)
70 | * .pcx (131 bytes)
71 | * .pgm (12 bytes)
72 | * .png (119 bytes)
73 | * .ppm (14 bytes)
74 | * .rle (58 bytes)
75 | * .tga (543 bytes)
76 | * .tif (250 bytes)
77 | * .tiff (250 bytes)
78 | * .wdp (300 bytes)
79 | * .webp (228 bytes)
80 | * .wmp (300 bytes)
81 |
82 | ### Sheet
83 |
84 | * .ods (2.7 KB)
85 | * .xlsx (4.5 KB)
86 |
87 | ### Slide
88 |
89 | * .odp (7.8 KB)
90 | * .pptx (13.3 KB)
91 |
92 |
93 | ## Consuming files as a web resource
94 |
95 | Files can be consumed as a web resource using the following url:
96 |
97 | ```
98 | https://github.com/VerifyTests/EmptyFiles/raw/main/index/empty.{extension}
99 | ```
100 |
101 | So for example to consume a jpg use
102 |
103 | ```
104 | https://github.com/VerifyTests/EmptyFiles/raw/main/index/empty.jpg
105 | ```
106 |
107 | A 404 will result for non-existent files.
108 |
109 |
110 | ## Tool Usage
111 |
112 |
113 | ### Installation
114 |
115 | Ensure [dotnet CLI is installed](https://docs.microsoft.com/en-us/dotnet/core/tools/).
116 |
117 | Install [EmptyFiles.Tool](https://nuget.org/packages/EmptyFiles.Tool/)
118 |
119 | ```ps
120 | dotnet tool install -g EmptyFiles.Tool
121 | ```
122 |
123 |
124 | ### Extension only Usage
125 |
126 | ```
127 | emptyfile bmp
128 | ```
129 |
130 | Creates `{CurrentDirectory}/empty.bmp`
131 |
132 |
133 | ### File Usage
134 |
135 | ```
136 | emptyfile myfile.bmp
137 | ```
138 |
139 | Creates `{CurrentDirectory}/myfile.bmp`
140 |
141 |
142 | ### Path Usage
143 |
144 | ```
145 | emptyfile path/myfile.bmp
146 | ```
147 |
148 | Creates `path/myfile.bmp`
149 |
150 |
151 | ## Library Usage
152 |
153 |
154 | ### CreateFile
155 |
156 | Creates a new empty file
157 |
158 |
159 |
160 | ```cs
161 | AllFiles.CreateFile(pathOfFileToCreate);
162 | ```
163 | snippet source | anchor
164 |
165 |
166 | Throws an exception if the extension is not known. There is also a `TryCreateFile` that will return false if the extension is not known.
167 |
168 | Use the optional `useEmptyStringForTextFiles` to create a empty text file if the extension is text. The file will be UTF8 no BOM as per https://www.unicode.org/versions/Unicode5.0.0/ch02.pdf "Use of a BOM is neither required nor recommended for UTF-8".
169 |
170 |
171 | ### GetPathFor
172 |
173 | Gets the path to an empty file for a given extension
174 |
175 |
176 |
177 | ```cs
178 | var path = AllFiles.GetPathFor(".jpg");
179 | ```
180 | snippet source | anchor
181 |
182 |
183 | Throws an exception if the extension is not known. There is also a `TryGetPathFor` that will return false if the extension is not known.
184 |
185 |
186 | ### IsEmptyFile
187 |
188 | Returns true if the target file is an empty file.
189 |
190 |
191 |
192 | ```cs
193 | var path = AllFiles.GetPathFor(".jpg");
194 | True(AllFiles.IsEmptyFile(path));
195 | var temp = Path.GetTempFileName();
196 | False(AllFiles.IsEmptyFile(temp));
197 | ```
198 | snippet source | anchor
199 |
200 |
201 |
202 | ### AllPaths
203 |
204 | Enumerates all empty files
205 |
206 |
207 |
208 | ```cs
209 | foreach (var path in AllFiles.AllPaths)
210 | {
211 | Trace.WriteLine(path);
212 | }
213 | ```
214 | snippet source | anchor
215 |
216 |
217 |
218 | ### UseFile
219 |
220 | Use or replace a file
221 |
222 |
223 |
224 | ```cs
225 | AllFiles.UseFile(Category.Document, pathToFile);
226 | IsTrue(AllFiles.DocumentPaths.Contains(pathToFile));
227 | ```
228 | snippet source | anchor
229 |
230 |
231 |
232 | ### Extensions helper
233 |
234 |
235 | #### IsText
236 |
237 | https://github.com/sindresorhus/text-extensions/blob/master/text-extensions.json
238 |
239 |
240 |
241 | ```cs
242 | True(FileExtensions.IsTextFile("file.txt"));
243 | False(FileExtensions.IsTextFile("file.bin"));
244 | True(FileExtensions.IsTextExtension(".txt"));
245 | False(FileExtensions.IsTextExtension(".bin"));
246 | True(FileExtensions.IsTextExtension("txt"));
247 | False(FileExtensions.IsTextExtension("bin"));
248 | ```
249 | snippet source | anchor
250 |
251 |
252 |
253 | #### AddTextExtension
254 |
255 |
256 |
257 | ```cs
258 | FileExtensions.AddTextExtension(".ext1");
259 | True(FileExtensions.IsTextExtension(".ext1"));
260 | True(FileExtensions.IsTextFile("file.ext1"));
261 | ```
262 | snippet source | anchor
263 |
264 |
265 |
266 | #### RemoveTextExtension
267 |
268 |
269 |
270 | ```cs
271 | FileExtensions.AddTextExtension(".ext1");
272 | True(FileExtensions.IsTextExtension(".ext1"));
273 | FileExtensions.RemoveTextExtension(".ext1");
274 | False(FileExtensions.IsTextExtension(".ext1"));
275 | ```
276 | snippet source | anchor
277 |
278 |
279 |
280 | #### AddTextFileConvention
281 |
282 | `AddTextFileConvention` allows the use of a convention based text file detection via a callback.
283 |
284 | At app startup add a convention using `FileExtensions.AddTextFileConvention`:
285 |
286 |
287 |
288 | ```cs
289 | [ModuleInitializer]
290 | public static void AddTextFileConvention() =>
291 | // Treat files ending with .txtViaConvention as text files
292 | FileExtensions.AddTextFileConvention(path => path.EndsWith(".txtViaConvention"));
293 | ```
294 | snippet source | anchor
295 |
296 |
297 | Then any call to `FileExtensions.IsTextFile` will, in addition to checking the known text extensions, also check if any of the added text contentions return true.
298 |
299 |
300 |
301 | ```cs
302 | True(FileExtensions.IsTextFile("c:/path/file.txtViaConvention"));
303 | ```
304 | snippet source | anchor
305 |
306 |
307 | An alternative approach to a text file convention would be to check if a file has a preamble that matches an known text encoding.
308 |
309 |
310 | ## Icon
311 |
312 | [Hollow](https://thenounproject.com/term/hollow/51835/) designed by [Michael Senkow](https://thenounproject.com/mhsenkow/) from [The Noun Project](https://thenounproject.com).
313 |
--------------------------------------------------------------------------------
/src/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 |
6 | [*.cs]
7 | indent_size = 4
8 | charset = utf-8
9 |
10 | # Redundant accessor body
11 | resharper_redundant_accessor_body_highlighting = error
12 |
13 | # Replace with field keyword
14 | resharper_replace_with_field_keyword_highlighting = error
15 |
16 | # Replace with single call to Single(..)
17 | resharper_replace_with_single_call_to_single_highlighting = error
18 |
19 | # Replace with single call to SingleOrDefault(..)
20 | resharper_replace_with_single_call_to_single_or_default_highlighting = error
21 |
22 | # Replace with single call to LastOrDefault(..)
23 | resharper_replace_with_single_call_to_last_or_default_highlighting = error
24 |
25 | # Replace with single call to Last(..)
26 | resharper_replace_with_single_call_to_last_highlighting = error
27 |
28 | # Replace with single call to First(..)
29 | resharper_replace_with_single_call_to_first_highlighting = error
30 |
31 | # Replace with single call to FirstOrDefault(..)
32 | resharper_replace_with_single_call_to_first_or_default_highlighting = error
33 |
34 | # Replace with single call to Any(..)
35 | resharper_replace_with_single_call_to_any_highlighting = error
36 |
37 | # Replace with single call to Count(..)
38 | resharper_replace_with_single_call_to_count_highlighting = error
39 |
40 | # Declare types in namespaces
41 | dotnet_diagnostic.CA1050.severity = none
42 |
43 | # Use Literals Where Appropriate
44 | dotnet_diagnostic.CA1802.severity = error
45 |
46 | # Template should be a static expression
47 | dotnet_diagnostic.CA2254.severity = error
48 |
49 | # Potentially misleading parameter name in lambda or local function
50 | resharper_all_underscore_local_parameter_name_highlighting = none
51 |
52 | # Redundant explicit collection creation in argument of 'params' parameter
53 | resharper_redundant_explicit_params_array_creation_highlighting = error
54 |
55 | # Do not initialize unnecessarily
56 | dotnet_diagnostic.CA1805.severity = error
57 |
58 | # Avoid unsealed attributes
59 | dotnet_diagnostic.CA1813.severity = error
60 |
61 | # Test for empty strings using string length
62 | dotnet_diagnostic.CA1820.severity = none
63 |
64 | # Remove empty finalizers
65 | dotnet_diagnostic.CA1821.severity = error
66 |
67 | # Mark members as static
68 | dotnet_diagnostic.CA1822.severity = error
69 |
70 | # Avoid unused private fields
71 | dotnet_diagnostic.CA1823.severity = error
72 |
73 | # Avoid zero-length array allocations
74 | dotnet_diagnostic.CA1825.severity = error
75 |
76 | # Use property instead of Linq Enumerable method
77 | dotnet_diagnostic.CA1826.severity = error
78 |
79 | # Do not use Count()/LongCount() when Any() can be used
80 | dotnet_diagnostic.CA1827.severity = error
81 | dotnet_diagnostic.CA1828.severity = error
82 |
83 | # Use Length/Count property instead of Enumerable.Count method
84 | dotnet_diagnostic.CA1829.severity = error
85 |
86 | # Prefer strongly-typed Append and Insert method overloads on StringBuilder
87 | dotnet_diagnostic.CA1830.severity = error
88 |
89 | # Use AsSpan instead of Range-based indexers for string when appropriate
90 | dotnet_diagnostic.CA1831.severity = error
91 |
92 | # Use AsSpan instead of Range-based indexers for string when appropriate
93 | dotnet_diagnostic.CA1831.severity = error
94 | dotnet_diagnostic.CA1832.severity = error
95 | dotnet_diagnostic.CA1833.severity = error
96 |
97 | # Use StringBuilder.Append(char) for single character strings
98 | dotnet_diagnostic.CA1834.severity = error
99 |
100 | # Prefer IsEmpty over Count when available
101 | dotnet_diagnostic.CA1836.severity = error
102 |
103 | # Prefer IsEmpty over Count when available
104 | dotnet_diagnostic.CA1836.severity = error
105 |
106 | # Use Environment.ProcessId instead of Process.GetCurrentProcess().Id
107 | dotnet_diagnostic.CA1837.severity = error
108 |
109 | # Use Environment.ProcessPath instead of Process.GetCurrentProcess().MainModule.FileName
110 | dotnet_diagnostic.CA1839.severity = error
111 |
112 | # Use Environment.CurrentManagedThreadId instead of Thread.CurrentThread.ManagedThreadId
113 | dotnet_diagnostic.CA1840.severity = error
114 |
115 | # Prefer Dictionary Contains methods
116 | dotnet_diagnostic.CA1841.severity = error
117 |
118 | # Do not use WhenAll with a single task
119 | dotnet_diagnostic.CA1842.severity = error
120 |
121 | # Do not use WhenAll/WaitAll with a single task
122 | dotnet_diagnostic.CA1842.severity = error
123 | dotnet_diagnostic.CA1843.severity = error
124 |
125 | # Use span-based 'string.Concat'
126 | dotnet_diagnostic.CA1845.severity = error
127 |
128 | # Prefer AsSpan over Substring
129 | dotnet_diagnostic.CA1846.severity = error
130 |
131 | # Use string.Contains(char) instead of string.Contains(string) with single characters
132 | dotnet_diagnostic.CA1847.severity = error
133 |
134 | # Prefer static HashData method over ComputeHash
135 | dotnet_diagnostic.CA1850.severity = error
136 |
137 | # Possible multiple enumerations of IEnumerable collection
138 | dotnet_diagnostic.CA1851.severity = error
139 |
140 | # Unnecessary call to Dictionary.ContainsKey(key)
141 | dotnet_diagnostic.CA1853.severity = error
142 |
143 | # Prefer the IDictionary.TryGetValue(TKey, out TValue) method
144 | dotnet_diagnostic.CA1854.severity = error
145 |
146 | # Use Span.Clear() instead of Span.Fill()
147 | dotnet_diagnostic.CA1855.severity = error
148 |
149 | # Incorrect usage of ConstantExpected attribute
150 | dotnet_diagnostic.CA1856.severity = error
151 |
152 | # The parameter expects a constant for optimal performance
153 | dotnet_diagnostic.CA1857.severity = error
154 |
155 | # Use StartsWith instead of IndexOf
156 | dotnet_diagnostic.CA1858.severity = error
157 |
158 | # Avoid using Enumerable.Any() extension method
159 | dotnet_diagnostic.CA1860.severity = error
160 |
161 | # Avoid constant arrays as arguments
162 | dotnet_diagnostic.CA1861.severity = error
163 |
164 | # Use the StringComparison method overloads to perform case-insensitive string comparisons
165 | dotnet_diagnostic.CA1862.severity = error
166 |
167 | # Prefer the IDictionary.TryAdd(TKey, TValue) method
168 | dotnet_diagnostic.CA1864.severity = error
169 |
170 | # Use string.Method(char) instead of string.Method(string) for string with single char
171 | dotnet_diagnostic.CA1865.severity = error
172 | dotnet_diagnostic.CA1866.severity = error
173 | dotnet_diagnostic.CA1867.severity = error
174 |
175 | # Unnecessary call to 'Contains' for sets
176 | dotnet_diagnostic.CA1868.severity = error
177 |
178 | # Cache and reuse 'JsonSerializerOptions' instances
179 | dotnet_diagnostic.CA1869.severity = error
180 |
181 | # Use a cached 'SearchValues' instance
182 | dotnet_diagnostic.CA1870.severity = error
183 |
184 | # Microsoft .NET properties
185 | trim_trailing_whitespace = true
186 | csharp_preferred_modifier_order = public, private, protected, internal, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async:suggestion
187 | resharper_namespace_body = file_scoped
188 | dotnet_naming_rule.private_constants_rule.severity = warning
189 | dotnet_naming_rule.private_constants_rule.style = lower_camel_case_style
190 | dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols
191 | dotnet_naming_rule.private_instance_fields_rule.severity = warning
192 | dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style
193 | dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols
194 | dotnet_naming_rule.private_static_fields_rule.severity = warning
195 | dotnet_naming_rule.private_static_fields_rule.style = lower_camel_case_style
196 | dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols
197 | dotnet_naming_rule.private_static_readonly_rule.severity = warning
198 | dotnet_naming_rule.private_static_readonly_rule.style = lower_camel_case_style
199 | dotnet_naming_rule.private_static_readonly_rule.symbols = private_static_readonly_symbols
200 | dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
201 | dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case
202 | dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private
203 | dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field
204 | dotnet_naming_symbols.private_constants_symbols.required_modifiers = const
205 | dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private
206 | dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field
207 | dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private
208 | dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field
209 | dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static
210 | dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private
211 | dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field
212 | dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static, readonly
213 | dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
214 | dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none
215 | dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
216 |
217 | # ReSharper properties
218 | resharper_object_creation_when_type_not_evident = target_typed
219 |
220 | # ReSharper inspection severities
221 | resharper_arrange_object_creation_when_type_evident_highlighting = error
222 | resharper_arrange_object_creation_when_type_not_evident_highlighting = error
223 | resharper_arrange_redundant_parentheses_highlighting = error
224 | resharper_arrange_static_member_qualifier_highlighting = error
225 | resharper_arrange_this_qualifier_highlighting = error
226 | resharper_arrange_type_member_modifiers_highlighting = none
227 | resharper_built_in_type_reference_style_for_member_access_highlighting = hint
228 | resharper_built_in_type_reference_style_highlighting = hint
229 | resharper_check_namespace_highlighting = none
230 | resharper_convert_to_using_declaration_highlighting = error
231 | resharper_css_not_resolved_highlighting = warning
232 | resharper_field_can_be_made_read_only_local_highlighting = none
233 | resharper_merge_into_logical_pattern_highlighting = warning
234 | resharper_merge_into_pattern_highlighting = error
235 | resharper_method_has_async_overload_highlighting = warning
236 | # because stop rider giving errors before source generators have run
237 | resharper_partial_type_with_single_part_highlighting = warning
238 | resharper_redundant_base_qualifier_highlighting = warning
239 | resharper_redundant_cast_highlighting = error
240 | resharper_redundant_empty_object_creation_argument_list_highlighting = error
241 | resharper_redundant_empty_object_or_collection_initializer_highlighting = error
242 | resharper_redundant_name_qualifier_highlighting = error
243 | resharper_redundant_suppress_nullable_warning_expression_highlighting = error
244 | resharper_redundant_using_directive_highlighting = error
245 | resharper_redundant_verbatim_string_prefix_highlighting = error
246 | resharper_redundant_lambda_signature_parentheses_highlighting = error
247 | resharper_replace_substring_with_range_indexer_highlighting = warning
248 | resharper_suggest_var_or_type_built_in_types_highlighting = error
249 | resharper_suggest_var_or_type_elsewhere_highlighting = error
250 | resharper_suggest_var_or_type_simple_types_highlighting = error
251 | resharper_unnecessary_whitespace_highlighting = error
252 | resharper_use_await_using_highlighting = warning
253 | resharper_use_deconstruction_highlighting = warning
254 |
255 | # Sort using and Import directives with System.* appearing first
256 | dotnet_sort_system_directives_first = true
257 |
258 | # Avoid "this." and "Me." if not necessary
259 | dotnet_style_qualification_for_field = false:error
260 | dotnet_style_qualification_for_property = false:error
261 | dotnet_style_qualification_for_method = false:error
262 | dotnet_style_qualification_for_event = false:error
263 |
264 | # Use language keywords instead of framework type names for type references
265 | dotnet_style_predefined_type_for_locals_parameters_members = true:error
266 | dotnet_style_predefined_type_for_member_access = true:error
267 |
268 | # Suggest more modern language features when available
269 | dotnet_style_object_initializer = true:error
270 | dotnet_style_collection_initializer = true:error
271 | dotnet_style_coalesce_expression = false:error
272 | dotnet_style_null_propagation = true:error
273 | dotnet_style_explicit_tuple_names = true:error
274 |
275 | # Prefer "var" everywhere
276 | csharp_style_var_for_built_in_types = true:error
277 | csharp_style_var_when_type_is_apparent = true:error
278 | csharp_style_var_elsewhere = true:error
279 |
280 | # Prefer method-like constructs to have a block body
281 | csharp_style_expression_bodied_methods = true:error
282 | csharp_style_expression_bodied_local_functions = true:error
283 | csharp_style_expression_bodied_constructors = true:error
284 | csharp_style_expression_bodied_operators = true:error
285 | resharper_place_expr_method_on_single_line = false
286 |
287 | # Prefer property-like constructs to have an expression-body
288 | csharp_style_expression_bodied_properties = true:error
289 | csharp_style_expression_bodied_indexers = true:error
290 | csharp_style_expression_bodied_accessors = true:error
291 |
292 | # Suggest more modern language features when available
293 | csharp_style_pattern_matching_over_is_with_cast_check = true:error
294 | csharp_style_pattern_matching_over_as_with_null_check = true:error
295 | csharp_style_inlined_variable_declaration = true:suggestion
296 | csharp_style_throw_expression = true:suggestion
297 | csharp_style_conditional_delegate_call = true:suggestion
298 |
299 | # Newline settings
300 | #csharp_new_line_before_open_brace = all:error
301 | resharper_max_array_initializer_elements_on_line = 1
302 | csharp_new_line_before_else = true
303 | csharp_new_line_before_catch = true
304 | csharp_new_line_before_finally = true
305 | csharp_new_line_before_members_in_object_initializers = true
306 | csharp_new_line_before_members_in_anonymous_types = true
307 | resharper_wrap_before_first_type_parameter_constraint = true
308 | resharper_wrap_extends_list_style = chop_always
309 | resharper_wrap_after_dot_in_method_calls = false
310 | resharper_wrap_before_binary_pattern_op = false
311 | resharper_wrap_object_and_collection_initializer_style = chop_always
312 | resharper_place_simple_initializer_on_single_line = false
313 |
314 | # space
315 | resharper_space_around_lambda_arrow = true
316 |
317 | dotnet_style_require_accessibility_modifiers = never:error
318 | resharper_place_type_constraints_on_same_line = false
319 | resharper_blank_lines_inside_namespace = 0
320 | resharper_blank_lines_after_file_scoped_namespace_directive = 1
321 | resharper_blank_lines_inside_type = 0
322 |
323 | insert_final_newline = false
324 | resharper_place_attribute_on_same_line = false
325 | resharper_space_around_lambda_arrow = true
326 | resharper_place_constructor_initializer_on_same_line = false
327 |
328 | #braces https://www.jetbrains.com/help/resharper/EditorConfig_CSHARP_CSharpCodeStylePageImplSchema.html#Braces
329 | resharper_braces_for_ifelse = required
330 | resharper_braces_for_foreach = required
331 | resharper_braces_for_while = required
332 | resharper_braces_for_dowhile = required
333 | resharper_braces_for_lock = required
334 | resharper_braces_for_fixed = required
335 | resharper_braces_for_for = required
336 |
337 | resharper_return_value_of_pure_method_is_not_used_highlighting = error
338 |
339 | resharper_all_underscore_local_parameter_name_highlighting = none
340 |
341 | resharper_misleading_body_like_statement_highlighting = error
342 |
343 | resharper_redundant_record_class_keyword_highlighting = error
344 |
345 | resharper_redundant_extends_list_entry_highlighting = error
346 |
347 | # Xml files
348 | [*.{xml,config,nuspec,resx,vsixmanifest,csproj,targets,props,fsproj}]
349 | indent_size = 2
350 | # https://www.jetbrains.com/help/resharper/EditorConfig_XML_XmlCodeStylePageSchema.html#resharper_xml_blank_line_after_pi
351 | resharper_blank_line_after_pi = false
352 | resharper_space_before_self_closing = true
353 | ij_xml_space_inside_empty_tag = true
354 |
355 | [*.json]
356 | indent_size = 2
357 |
358 | # Verify settings
359 | [*.{received,verified}.{txt,xml,json,md,sql,csv,html,htm,md}]
360 | charset = utf-8-bom
361 | end_of_line = lf
362 | indent_size = unset
363 | indent_style = unset
364 | insert_final_newline = false
365 | tab_width = unset
366 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/src/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CS1591;CS0649;NU5119;NU1608;NU1109
5 | 8.10.0
6 | preview
7 | 1.0.0
8 | A collection of minimal binary files.
9 | false
10 | true
11 | true
12 | true
13 | true
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/Directory.Packages.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 | true
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/EmptyFiles.Tool/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | [assembly: InternalsVisibleTo("Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e191859fcd1deee68b96927c170783ced0c9a471a6424a0a011cfd31156a49dd73c4ad4a88b995fb918c0b43e0c005ef5fb72d53a328a64bde825cb5f2e4c53d66f69fcbb87d6737128b98e677a42091974b5f56093123a2dd6bc738af751b101d41c4f7a996e217b61967a3aa1ae7bc791d19c1cbeef47f0cdd20d288dff1a3")]
--------------------------------------------------------------------------------
/src/EmptyFiles.Tool/EmptyFiles.Tool.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | net8.0
5 | emptyfile
6 | emptyfile
7 | EmptyFiles.Tool
8 | True
9 | .NET Core Global Tool for creating minimal binary files
10 | true
11 | $(NoWarn);NU5118;NU5119
12 | LatestMajor
13 |
14 |
15 |
16 |
17 |
18 | true
19 | tools\net8.0\any\EmptyFiles
20 |
21 |
22 | EmptyFiles\%(RecursiveDir)%(Filename)%(Extension)
23 | PreserveNewest
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/EmptyFiles.Tool/Program.cs:
--------------------------------------------------------------------------------
1 | using EmptyFiles;
2 |
3 | if (args.Length == 0)
4 | {
5 | Console.Error.Write("No input");
6 | return 1;
7 | }
8 |
9 | var arg = args[0];
10 |
11 | string path;
12 | if (arg.Any(_ => _ is
13 | '.' or
14 | '/' or
15 | '\\'))
16 | {
17 | path = arg;
18 | }
19 | else
20 | {
21 | path = $"empty.{arg}";
22 | }
23 |
24 | if (AllFiles.TryCreateFile(
25 | path,
26 | useEmptyStringForTextFiles: true))
27 | {
28 | return 0;
29 | }
30 |
31 | Console.Error.Write("Unknown extension");
32 | return 1;
--------------------------------------------------------------------------------
/src/EmptyFiles.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29201.188
5 | MinimumVisualStudioVersion = 16.0.29201.188
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9A6C4741-C83D-4E05-A62F-8049F65B9B6C}"
7 | ProjectSection(SolutionItems) = preProject
8 | .editorconfig = .editorconfig
9 | appveyor.yml = appveyor.yml
10 | Directory.Build.props = Directory.Build.props
11 | Directory.Packages.props = Directory.Packages.props
12 | ..\readme.md = ..\readme.md
13 | global.json = global.json
14 | mdsnippets.json = mdsnippets.json
15 | EndProjectSection
16 | EndProject
17 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EmptyFiles", "EmptyFiles\EmptyFiles.csproj", "{A017D3FD-7DA5-4DF4-A169-72DE4AF76048}"
18 | EndProject
19 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{C4875357-5EF0-40DC-9E53-0F5B0236534F}"
20 | EndProject
21 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EmptyFiles.Tool", "EmptyFiles.Tool\EmptyFiles.Tool.csproj", "{C0E127A1-493E-4CB9-A0B9-ACBBA5BB3D2C}"
22 | EndProject
23 | Global
24 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
25 | Debug|Any CPU = Debug|Any CPU
26 | Release|Any CPU = Release|Any CPU
27 | EndGlobalSection
28 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
29 | {A017D3FD-7DA5-4DF4-A169-72DE4AF76048}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 | {A017D3FD-7DA5-4DF4-A169-72DE4AF76048}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 | {A017D3FD-7DA5-4DF4-A169-72DE4AF76048}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {A017D3FD-7DA5-4DF4-A169-72DE4AF76048}.Release|Any CPU.Build.0 = Release|Any CPU
33 | {C4875357-5EF0-40DC-9E53-0F5B0236534F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {C4875357-5EF0-40DC-9E53-0F5B0236534F}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {C4875357-5EF0-40DC-9E53-0F5B0236534F}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {C4875357-5EF0-40DC-9E53-0F5B0236534F}.Release|Any CPU.Build.0 = Release|Any CPU
37 | {C0E127A1-493E-4CB9-A0B9-ACBBA5BB3D2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38 | {C0E127A1-493E-4CB9-A0B9-ACBBA5BB3D2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
39 | {C0E127A1-493E-4CB9-A0B9-ACBBA5BB3D2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
40 | {C0E127A1-493E-4CB9-A0B9-ACBBA5BB3D2C}.Release|Any CPU.Build.0 = Release|Any CPU
41 | EndGlobalSection
42 | GlobalSection(SolutionProperties) = preSolution
43 | HideSolutionNode = FALSE
44 | EndGlobalSection
45 | GlobalSection(ExtensibilityGlobals) = postSolution
46 | SolutionGuid = {B0B94980-5385-4EC6-A0EE-C9A191DDFC05}
47 | EndGlobalSection
48 | EndGlobal
49 |
--------------------------------------------------------------------------------
/src/EmptyFiles.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | ..\Shared.sln.DotSettings
3 | True
4 | True
5 | 1
6 |
--------------------------------------------------------------------------------
/src/EmptyFiles.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/src/EmptyFiles/AllFiles.cs:
--------------------------------------------------------------------------------
1 | namespace EmptyFiles;
2 |
3 | public static class AllFiles
4 | {
5 | public static FrozenDictionary Files => files;
6 |
7 | static FrozenDictionary files;
8 |
9 | public static FrozenDictionary Archives => archives;
10 |
11 | static FrozenDictionary archives;
12 |
13 | public static FrozenDictionary Documents => documents;
14 |
15 | static FrozenDictionary documents;
16 |
17 | public static FrozenDictionary Images => images;
18 |
19 | static FrozenDictionary images;
20 |
21 | public static FrozenDictionary Sheets => sheets;
22 |
23 | static FrozenDictionary sheets;
24 |
25 | public static FrozenDictionary Slides => slides;
26 |
27 | static FrozenDictionary slides;
28 |
29 | static AllFiles()
30 | {
31 | var directory = FindEmptyFilesDirectory();
32 |
33 | archives = AddCategory(archiveExtensions, Category.Archive, directory);
34 | documents = AddCategory(documentExtensions, Category.Document, directory);
35 | images = AddCategory(imageExtensions, Category.Image, directory);
36 | sheets = AddCategory(sheetExtensions, Category.Sheet, directory);
37 | slides = AddCategory(slideExtensions, Category.Slide, directory);
38 | var all = new Dictionary();
39 | Append(archives);
40 | Append(documents);
41 | Append(images);
42 | Append(sheets);
43 | Append(slides);
44 |
45 | files = all.ToFrozenDictionary();
46 |
47 | void Append(FrozenDictionary files)
48 | {
49 | foreach (var (key, value) in files)
50 | {
51 | all[key] = value;
52 | }
53 | }
54 | }
55 |
56 | static FrozenDictionary AddCategory(FrozenSet extensions, Category category, string emptyDirectory)
57 | {
58 | Dictionary items = [];
59 | var categoryDirectory = Path.Combine(
60 | emptyDirectory,
61 | category
62 | .ToString()
63 | .ToLowerInvariant());
64 | foreach (var extension in extensions)
65 | {
66 | var file = Path.Combine(categoryDirectory, $"empty{extension}");
67 | items[extension] = EmptyFile.Build(file, category);
68 | }
69 |
70 | return items.ToFrozenDictionary();
71 | }
72 |
73 | static string FindEmptyFilesDirectory()
74 | {
75 | var directories = FindDirectories()
76 | .Select(_ => Path.Combine(_, "EmptyFiles"))
77 | .ToList();
78 | foreach (var directory in directories)
79 | {
80 | if (Directory.Exists(directory))
81 | {
82 | return directory;
83 | }
84 | }
85 |
86 | throw new(
87 | $"""
88 | Could not find empty files directory. Searched:
89 | {string.Join(Environment.NewLine, directories)}
90 | """);
91 | }
92 |
93 | static IEnumerable FindDirectories()
94 | {
95 | yield return AppDomain.CurrentDomain.BaseDirectory;
96 | yield return AssemblyLocation.Directory;
97 | yield return Environment.CurrentDirectory;
98 | }
99 |
100 | public static void UseFile(Category category, string file)
101 | {
102 | Guard.FileExists(file);
103 | var extension = Path.GetExtension(file);
104 | var emptyFile = EmptyFile.Build(file, category);
105 | switch (category)
106 | {
107 | case Category.Archive:
108 | Init(ref archives, ref archiveExtensions);
109 | break;
110 | case Category.Document:
111 | Init(ref documents, ref documentExtensions);
112 | break;
113 | case Category.Image:
114 | Init(ref images, ref imageExtensions);
115 | break;
116 | case Category.Sheet:
117 | Init(ref sheets, ref sheetExtensions);
118 | break;
119 | case Category.Slide:
120 | Init(ref slides, ref slideExtensions);
121 | break;
122 | default:
123 | throw new($"Unknown category: {category}");
124 | }
125 |
126 | void Init(ref FrozenDictionary emptyFiles, ref FrozenSet extensions)
127 | {
128 | var tempDictionary = new Dictionary();
129 | foreach (var (key, value) in emptyFiles)
130 | {
131 | tempDictionary[key] = value;
132 | }
133 |
134 | tempDictionary[extension] = emptyFile;
135 | emptyFiles = tempDictionary.ToFrozenDictionary();
136 | var tempSet = new HashSet(extensions)
137 | {
138 | extension
139 | };
140 | extensions = tempSet.ToFrozenSet();
141 | }
142 | }
143 |
144 | public static IEnumerable AllPaths => files.Values.Select(_ => _.Path);
145 |
146 | // ReSharper disable once UseSymbolAlias
147 | public static IReadOnlyCollection AllExtensions => files.Keys;
148 |
149 | public static IEnumerable ArchivePaths => archives.Values.Select(_ => _.Path);
150 |
151 | public static FrozenSet ArchiveExtensions => archiveExtensions;
152 |
153 | static FrozenSet archiveExtensions = FrozenSet.ToFrozenSet(
154 | [
155 | ".7z",
156 | ".7zip",
157 | ".bz2",
158 | ".bzip2",
159 | ".gz",
160 | ".gzip",
161 | ".tar",
162 | ".xz",
163 | ".zip"
164 | ]);
165 |
166 | public static IEnumerable DocumentPaths => documents.Values.Select(_ => _.Path);
167 |
168 | public static FrozenSet DocumentExtensions => documentExtensions;
169 |
170 | static FrozenSet documentExtensions = FrozenSet.ToFrozenSet(
171 | [
172 | ".docx",
173 | ".odt",
174 | ".pdf",
175 | ".rtf"
176 | ]);
177 |
178 | public static IEnumerable ImagePaths => images.Values.Select(_ => _.Path);
179 |
180 | public static FrozenSet ImageExtensions => imageExtensions;
181 |
182 | static FrozenSet imageExtensions = FrozenSet.ToFrozenSet(
183 | [
184 | ".avif",
185 | ".bmp",
186 | ".dds",
187 | ".dib",
188 | ".emf",
189 | ".exif",
190 | ".gif",
191 | ".heic",
192 | ".heif",
193 | ".ico",
194 | ".j2c",
195 | ".jfif",
196 | ".jp2",
197 | ".jpc",
198 | ".jpe",
199 | ".jpeg",
200 | ".jpg",
201 | ".jxr",
202 | ".pbm",
203 | ".pcx",
204 | ".pgm",
205 | ".png",
206 | ".ppm",
207 | ".rle",
208 | ".tga",
209 | ".tif",
210 | ".tiff",
211 | ".wdp",
212 | ".webp",
213 | ".wmp"
214 | ]);
215 |
216 | public static IEnumerable SheetPaths => sheets.Values.Select(_ => _.Path);
217 |
218 | public static FrozenSet SheetExtensions => sheetExtensions;
219 |
220 | static FrozenSet sheetExtensions = FrozenSet.ToFrozenSet(
221 | [
222 | ".ods",
223 | ".xlsx"
224 | ]);
225 |
226 | public static IEnumerable SlidePaths => slides.Values.Select(_ => _.Path);
227 |
228 | public static FrozenSet SlideExtensions => slideExtensions;
229 |
230 | static FrozenSet slideExtensions = FrozenSet.ToFrozenSet(
231 | [
232 | ".odp",
233 | ".pptx"
234 | ]);
235 |
236 | public static bool IsEmptyFile(string path)
237 | {
238 | Guard.FileExists(path);
239 | var extension = Path.GetExtension(path);
240 | if (!files.TryGetValue(extension, out var emptyFile))
241 | {
242 | return false;
243 | }
244 |
245 | return File.GetLastWriteTime(path) == emptyFile.LastWriteTime;
246 | }
247 |
248 | public static void CreateFile(string path, bool useEmptyStringForTextFiles = false, Encoding? encoding = null)
249 | {
250 | TryCreateDirectory(path);
251 | var extension = Path.GetExtension(path);
252 | if (useEmptyStringForTextFiles &&
253 | FileExtensions.IsTextExtension(extension))
254 | {
255 | CreateTextFile(path, encoding);
256 | return;
257 | }
258 |
259 | File.Copy(GetPathFor(extension), path, true);
260 | }
261 |
262 | static void CreateTextFile(string path, Encoding? encoding)
263 | {
264 | File.Delete(path);
265 | encoding ??= Encoding.UTF8;
266 | File.WriteAllBytes(path, encoding.GetPreamble());
267 | }
268 |
269 | public static string GetPathFor(string extension)
270 | {
271 | extension = Guard.ValidExtension(extension);
272 | if (files.TryGetValue(extension, out var emptyFile))
273 | {
274 | return emptyFile.Path;
275 | }
276 |
277 | throw new($"Unknown extension: {extension}");
278 | }
279 |
280 | public static bool TryCreateFile(string path, bool useEmptyStringForTextFiles = false, Encoding? encoding = null)
281 | {
282 | Guard.AgainstNullOrEmpty(path);
283 | var extension = Path.GetExtension(path);
284 |
285 | if (useEmptyStringForTextFiles &&
286 | FileExtensions.IsTextExtension(extension))
287 | {
288 | TryCreateDirectory(path);
289 |
290 | CreateTextFile(path, encoding);
291 | return true;
292 | }
293 |
294 | if (!TryGetPathFor(extension, out var source))
295 | {
296 | return false;
297 | }
298 |
299 | TryCreateDirectory(path);
300 |
301 | File.Copy(source, path, true);
302 | return true;
303 | }
304 |
305 | static void TryCreateDirectory(string path)
306 | {
307 | var directory = Path.GetDirectoryName(path);
308 |
309 | if (!string.IsNullOrWhiteSpace(directory))
310 | {
311 | Directory.CreateDirectory(directory);
312 | }
313 | }
314 |
315 | public static bool TryGetPathFor(string extension, [NotNullWhen(true)] out string? path)
316 | {
317 | if (files.TryGetValue(extension, out var emptyFile))
318 | {
319 | path = emptyFile.Path;
320 | return true;
321 | }
322 |
323 | path = null;
324 | return false;
325 | }
326 | }
--------------------------------------------------------------------------------
/src/EmptyFiles/AssemblyLocation.cs:
--------------------------------------------------------------------------------
1 | static class AssemblyLocation
2 | {
3 | static AssemblyLocation()
4 | {
5 | var assembly = typeof(AssemblyLocation).Assembly;
6 | #if NET5_0_OR_GREATER
7 | Path = assembly.Location;
8 | #else
9 | var uri = new UriBuilder(assembly.CodeBase);
10 | Path = Uri.UnescapeDataString(uri.Path);
11 | #endif
12 |
13 | Directory = System.IO.Path.GetDirectoryName(Path)!;
14 | }
15 |
16 | public static string Path;
17 |
18 | public static string Directory;
19 | }
--------------------------------------------------------------------------------
/src/EmptyFiles/Category.cs:
--------------------------------------------------------------------------------
1 | namespace EmptyFiles;
2 |
3 | public enum Category
4 | {
5 | Archive,
6 | Document,
7 | Image,
8 | Sheet,
9 | Slide
10 | }
--------------------------------------------------------------------------------
/src/EmptyFiles/ClsCompliant.cs:
--------------------------------------------------------------------------------
1 | [assembly: CLSCompliant(true)]
--------------------------------------------------------------------------------
/src/EmptyFiles/ContentTypes.cs:
--------------------------------------------------------------------------------
1 | namespace EmptyFiles;
2 |
3 | public static class ContentTypes
4 | {
5 | public static bool IsText(string? mediaType) =>
6 | IsText(mediaType, out _);
7 |
8 | public static bool IsText(string? mediaType, [NotNullWhen(true)] out string? extension)
9 | {
10 | if (TryGetExtension(mediaType, out extension))
11 | {
12 | if (FileExtensions.IsTextExtension(extension))
13 | {
14 | return true;
15 | }
16 | }
17 |
18 | extension = null;
19 | return false;
20 | }
21 |
22 | public static bool TryGetExtension(string? mediaType, [NotNullWhen(true)] out string? extension)
23 | {
24 | if (mediaType == null)
25 | {
26 | extension = null;
27 | return false;
28 | }
29 |
30 | var indexOf = mediaType.IndexOf(';');
31 | if(indexOf != -1)
32 | {
33 | mediaType = mediaType[..indexOf];
34 | }
35 |
36 | if (mappings.TryGetValue(mediaType, out extension))
37 | {
38 | return true;
39 | }
40 |
41 | var mediaTypeSpan = mediaType.AsSpan();
42 | var plusIndex = mediaTypeSpan.LastIndexOf('+');
43 |
44 | if (plusIndex > -1)
45 | {
46 | extension = mediaTypeSpan[(plusIndex + 1)..]
47 | .ToString();
48 | return true;
49 | }
50 |
51 | var slashIndex = mediaTypeSpan.LastIndexOf('/');
52 |
53 | if (slashIndex > -1)
54 | {
55 | extension = mediaTypeSpan[(slashIndex + 1)..]
56 | .ToString();
57 | return true;
58 | }
59 |
60 | return false;
61 | }
62 |
63 | static Dictionary mappings = new(StringComparer.OrdinalIgnoreCase)
64 | {
65 | //extra
66 | {
67 | "application/graphql", "gql"
68 | },
69 | {
70 | "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx"
71 | },
72 | {
73 | "application/vnd.openxmlformats-officedocument.wordprocessingml.template", "dotx"
74 | },
75 | {
76 | "application/vnd.ms-word.document.macroEnabled.12", "docm"
77 | },
78 | {
79 | "application/vnd.ms-word.template.macroEnabled.12", "dotm"
80 | },
81 | {
82 | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx"
83 | },
84 | {
85 | "application/vnd.openxmlformats-officedocument.spreadsheetml.template", "xltx"
86 | },
87 | {
88 | "application/vnd.ms-excel.sheet.macroEnabled.12", "xlsm"
89 | },
90 | {
91 | "application/vnd.ms-excel.template.macroEnabled.12", "xltm"
92 | },
93 | {
94 | "application/vnd.ms-excel.addin.macroEnabled.12", "xlam"
95 | },
96 | {
97 | "application/vnd.ms-excel.sheet.binary.macroEnabled.12", "xlsb"
98 | },
99 | {
100 | "application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx"
101 | },
102 | {
103 | "application/vnd.openxmlformats-officedocument.presentationml.template", "potx"
104 | },
105 | {
106 | "application/vnd.openxmlformats-officedocument.presentationml.slideshow", "ppsx"
107 | },
108 | {
109 | "application/vnd.ms-powerpoint.addin.macroEnabled.12", "ppam"
110 | },
111 | {
112 | "application/vnd.ms-powerpoint.presentation.macroEnabled.12", "pptm"
113 | },
114 | {
115 | "application/vnd.ms-powerpoint.template.macroEnabled.12", "potm"
116 | },
117 | {
118 | "application/vnd.ms-powerpoint.slideshow.macroEnabled.12", "ppsm"
119 | },
120 |
121 | {
122 | "application/fsharp-script", "fsx"
123 | },
124 | {
125 | "application/msaccess", "adp"
126 | },
127 | {
128 | "application/msword", "doc"
129 | },
130 | {
131 | "application/octet-stream", "bin"
132 | },
133 | {
134 | "application/onenote", "one"
135 | },
136 | {
137 | "application/postscript", "eps"
138 | },
139 | {
140 | "application/soap+xml", "xml"
141 | },
142 | {
143 | "application/step", "step"
144 | },
145 | {
146 | "application/vnd.ms-excel", "xls"
147 | },
148 | {
149 | "application/vnd.ms-powerpoint", "ppt"
150 | },
151 | {
152 | "application/vnd.ms-works", "wks"
153 | },
154 | {
155 | "application/vnd.visio", "vsd"
156 | },
157 | {
158 | "application/x-director", "dir"
159 | },
160 | {
161 | "application/x-msdos-program", "exe"
162 | },
163 | {
164 | "application/x-shockwave-flash", "swf"
165 | },
166 | {
167 | "application/x-x509-ca-cert", "cer"
168 | },
169 | {
170 | "application/x-zip-compressed", "zip"
171 | },
172 | {
173 | "application/xhtml+xml", "xhtml"
174 | },
175 | {
176 | "application/xrd+xml", "xml"
177 | },
178 | {
179 | "application/xml", "xml"
180 | },
181 | {
182 | "audio/aac", "aac"
183 | },
184 | {
185 | "audio/aiff", "aiff"
186 | },
187 | {
188 | "audio/basic", "snd"
189 | },
190 | {
191 | "audio/mid", "midi"
192 | },
193 | {
194 | "audio/mp4", "m4a"
195 | },
196 | {
197 | "audio/wav", "wav"
198 | },
199 | {
200 | "audio/x-m4a", "m4a"
201 | },
202 | {
203 | "audio/x-mpegurl", "m3u"
204 | },
205 | {
206 | "audio/x-pn-realaudio", "ra"
207 | },
208 | {
209 | "audio/x-smd", "smd"
210 | },
211 | {
212 | "image/bmp", "bmp"
213 | },
214 | {
215 | "image/heic", ".heic"
216 | },
217 | {
218 | "image/heic-sequence", "heics"
219 | },
220 | {
221 | "image/jpeg", "jpg"
222 | },
223 | {
224 | "image/gif", "gif"
225 | },
226 | {
227 | "image/pict", "pic"
228 | },
229 | {
230 | "image/png", "png"
231 | },
232 | {
233 | "image/x-png", "png"
234 | },
235 | {
236 | "image/svg+xml", "svg"
237 | },
238 | {
239 | "image/tiff", "tiff"
240 | },
241 | {
242 | "image/x-macpaint", "mac"
243 | },
244 | {
245 | "image/x-quicktime", "qti"
246 | },
247 | {
248 | "message/rfc822", "eml"
249 | },
250 | {
251 | "text/calendar", "ics"
252 | },
253 | {
254 | "text/html", "html"
255 | },
256 | {
257 | "text/htmx", "htmx"
258 | },
259 | {
260 | "text/javascript", "js"
261 | },
262 | {
263 | "text/plain", "txt"
264 | },
265 | {
266 | "text/scriptlet", "wsc"
267 | },
268 | {
269 | "text/xml", "xml"
270 | },
271 | {
272 | "text/csv", "csv"
273 | },
274 | {
275 | "video/3gpp", "3gp"
276 | },
277 | {
278 | "video/3gpp2", "3gp2"
279 | },
280 | {
281 | "video/mp4", "mp4"
282 | },
283 | {
284 | "video/mpeg", "mpg"
285 | },
286 | {
287 | "video/quicktime", "mov"
288 | },
289 | {
290 | "video/vnd.dlna.mpeg-tts", "m2t"
291 | },
292 | {
293 | "video/x-dv", "dv"
294 | },
295 | {
296 | "video/x-la-asf", "lsf"
297 | },
298 | {
299 | "video/x-ms-asf", "asf"
300 | },
301 | {
302 | "x-world/x-vrml", "xof"
303 | }
304 | };
305 | }
--------------------------------------------------------------------------------
/src/EmptyFiles/EmptyFile.cs:
--------------------------------------------------------------------------------
1 | namespace EmptyFiles;
2 |
3 | public class EmptyFile
4 | {
5 | public string Path { get; }
6 | public DateTime LastWriteTime { get; }
7 | public Category Category { get; }
8 |
9 | internal static EmptyFile Build(string file, Category category)
10 | {
11 | var writeTime = File.GetLastWriteTime(file);
12 | return new(file, writeTime, category);
13 | }
14 |
15 | public EmptyFile(string path, in DateTime lastWriteTime, in Category category)
16 | {
17 | Guard.AgainstNullOrEmpty(path);
18 | Path = path;
19 | LastWriteTime = lastWriteTime;
20 | Category = category;
21 | }
22 | }
--------------------------------------------------------------------------------
/src/EmptyFiles/EmptyFiles.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net462;net472;net48
4 | $(TargetFrameworks);net6.0;net7.0;net8.0;net9.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | true
17 | files
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/EmptyFiles/FileExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace EmptyFiles;
2 |
3 | public static class FileExtensions
4 | {
5 | public static bool IsTextExtension(string extension)
6 | {
7 | extension = Guard.ValidExtension(extension);
8 |
9 | return textExtensions.Contains(extension);
10 | }
11 |
12 | public static bool IsTextExtension(CharSpan extension) =>
13 | IsTextExtension(extension.ToString());
14 |
15 | public static bool IsTextFile(string path) =>
16 | IsTextFile(path.AsSpan());
17 |
18 | public static bool IsTextFile(CharSpan path)
19 | {
20 | foreach (var convention in textFileConventions)
21 | {
22 | if (convention(path))
23 | {
24 | return true;
25 | }
26 | }
27 |
28 | var extension = PathPolyfill.GetExtension(path);
29 |
30 | if (extension.Length == 0)
31 | {
32 | return false;
33 | }
34 |
35 | return IsTextExtension(extension);
36 | }
37 |
38 | public static void RemoveTextExtension(string extension)
39 | {
40 | extension = Guard.ValidExtension(extension);
41 | var copy = new HashSet(textExtensions);
42 | copy.Remove(extension);
43 | textExtensions = copy.ToFrozenSet();
44 | }
45 |
46 | public static void RemoveTextExtension(CharSpan extension) =>
47 | RemoveTextExtension(extension.ToString());
48 |
49 | public static void RemoveTextExtensions(params string[] extensions)
50 | {
51 | foreach (var extension in extensions)
52 | {
53 | RemoveTextExtension(extension);
54 | }
55 | }
56 |
57 | public static void RemoveTextExtensions(IEnumerable extensions)
58 | {
59 | foreach (var extension in extensions)
60 | {
61 | RemoveTextExtension(extension);
62 | }
63 | }
64 |
65 | public static void AddTextExtension(string extension)
66 | {
67 | extension = Guard.ValidExtension(extension);
68 | var copy = new HashSet(textExtensions)
69 | {
70 | extension
71 | };
72 | textExtensions = copy.ToFrozenSet();
73 | }
74 |
75 | public static void AddTextExtension(CharSpan extension) =>
76 | AddTextExtension(extension.ToString());
77 |
78 | public static void AddTextExtensions(params string[] extensions)
79 | {
80 | foreach (var extension in extensions)
81 | {
82 | AddTextExtension(extension);
83 | }
84 | }
85 |
86 | public static void AddTextExtensions(IEnumerable extensions)
87 | {
88 | foreach (var extension in extensions)
89 | {
90 | AddTextExtension(extension);
91 | }
92 | }
93 |
94 | public static void AddTextFileConvention(IsTextFile convention) =>
95 | textFileConventions.Add(convention);
96 |
97 | static List textFileConventions = [];
98 |
99 | //From https://github.com/sindresorhus/text-extensions/blob/master/text-extensions.json
100 | static IReadOnlyCollection textExtensions = new HashSet
101 | {
102 | ".ada",
103 | ".adb",
104 | ".ads",
105 | ".applescript",
106 | ".as",
107 | ".asc",
108 | ".ascii",
109 | ".ascx",
110 | ".asm",
111 | ".asmx",
112 | ".asp",
113 | ".aspx",
114 | ".atom",
115 | ".au3",
116 | ".awk",
117 | ".bas",
118 | ".bash",
119 | ".bashrc",
120 | ".bat",
121 | ".bbcolors",
122 | ".bcp",
123 | ".bdsgroup",
124 | ".bdsproj",
125 | ".bib",
126 | ".bicep",
127 | ".bowerrc",
128 | ".c",
129 | ".cbl",
130 | ".cc",
131 | ".cfc",
132 | ".cfg",
133 | ".cfm",
134 | ".cfml",
135 | ".cgi",
136 | ".cjs",
137 | ".clj",
138 | ".cljs",
139 | ".cls",
140 | ".cmake",
141 | ".cmd",
142 | ".cnf",
143 | ".cob",
144 | ".code-snippets",
145 | ".coffee",
146 | ".coffeekup",
147 | ".conf",
148 | ".config",
149 | ".cp",
150 | ".cpp",
151 | ".cpt",
152 | ".cpy",
153 | ".crt",
154 | ".cs",
155 | ".csh",
156 | ".cson",
157 | ".csproj",
158 | ".csr",
159 | ".css",
160 | ".csslintrc",
161 | ".csv",
162 | ".ctl",
163 | ".curlrc",
164 | ".cxx",
165 | ".d",
166 | ".dart",
167 | ".dfm",
168 | ".diff",
169 | ".dof",
170 | ".dpk",
171 | ".dpr",
172 | ".dproj",
173 | ".dtd",
174 | ".dockerfile",
175 | ".eco",
176 | ".editorconfig",
177 | ".ejs",
178 | ".el",
179 | ".elm",
180 | ".emacs",
181 | ".eml",
182 | ".ent",
183 | ".env",
184 | ".erb",
185 | ".erl",
186 | ".eslintignore",
187 | ".eslintrc",
188 | ".ex",
189 | ".exs",
190 | ".f",
191 | ".f03",
192 | ".f77",
193 | ".f90",
194 | ".f95",
195 | ".fish",
196 | ".for",
197 | ".fpp",
198 | ".frm",
199 | ".fs",
200 | ".fsproj",
201 | ".fsx",
202 | ".ftn",
203 | ".gemrc",
204 | ".gemspec",
205 | ".gitattributes",
206 | ".gitconfig",
207 | ".gitignore",
208 | ".gitkeep",
209 | ".gitmodules",
210 | ".go",
211 | ".gpp",
212 | ".gradle",
213 | ".graphql",
214 | ".groovy",
215 | ".groupproj",
216 | ".grunit",
217 | ".gtmpl",
218 | ".gv",
219 | ".gvimrc",
220 | ".h",
221 | ".haml",
222 | ".hbs",
223 | ".hgignore",
224 | ".hh",
225 | ".hpp",
226 | ".hrl",
227 | ".hs",
228 | ".hta",
229 | ".htaccess",
230 | ".htc",
231 | ".htm",
232 | ".html",
233 | ".htmx",
234 | ".htpasswd",
235 | ".hxx",
236 | ".ics",
237 | ".iced",
238 | ".il",
239 | ".iml",
240 | ".inc",
241 | ".inf",
242 | ".info",
243 | ".ini",
244 | ".ino",
245 | ".int",
246 | ".irbrc",
247 | ".itcl",
248 | ".itermcolors",
249 | ".itk",
250 | ".jade",
251 | ".java",
252 | ".jhtm",
253 | ".jhtml",
254 | ".js",
255 | ".javascript",
256 | ".jscsrc",
257 | ".jshintignore",
258 | ".jshintrc",
259 | ".json",
260 | ".json5",
261 | ".jsonld",
262 | ".jsp",
263 | ".jspx",
264 | ".jsx",
265 | ".ksh",
266 | ".less",
267 | ".lhs",
268 | ".lisp",
269 | ".log",
270 | ".ls",
271 | ".lsp",
272 | ".lua",
273 | ".m",
274 | ".m4",
275 | ".mak",
276 | ".map",
277 | ".markdown",
278 | ".master",
279 | ".md",
280 | ".mdown",
281 | ".mdwn",
282 | ".mdx",
283 | ".mermaid",
284 | ".metadata",
285 | ".mht",
286 | ".mhtml",
287 | ".mjs",
288 | ".mk",
289 | ".mkd",
290 | ".mkdn",
291 | ".mkdown",
292 | ".ml",
293 | ".mli",
294 | ".mm",
295 | ".mmd",
296 | ".mxml",
297 | ".nfm",
298 | ".nfo",
299 | ".noon",
300 | ".npmignore",
301 | ".npmrc",
302 | ".nuspec",
303 | ".nvmrc",
304 | ".ops",
305 | ".pas",
306 | ".pasm",
307 | ".patch",
308 | ".pbxproj",
309 | ".pch",
310 | ".pem",
311 | ".pg",
312 | ".php",
313 | ".php3",
314 | ".php4",
315 | ".php5",
316 | ".phpt",
317 | ".phtml",
318 | ".pir",
319 | ".pl",
320 | ".pm",
321 | ".pmc",
322 | ".pod",
323 | ".pot",
324 | ".prettierrc",
325 | ".properties",
326 | ".props",
327 | ".ps1",
328 | ".pt",
329 | ".pug",
330 | ".purs",
331 | ".py",
332 | ".pyx",
333 | ".r",
334 | ".rake",
335 | ".rb",
336 | ".rbw",
337 | ".rc",
338 | ".rdoc",
339 | ".rdoc_options",
340 | ".resx",
341 | ".rexx",
342 | ".rhtml",
343 | ".rjs",
344 | ".rlib",
345 | ".ron",
346 | ".rs",
347 | ".rss",
348 | ".rst",
349 | ".rtf",
350 | ".rvmrc",
351 | ".rxml",
352 | ".s",
353 | ".sass",
354 | ".scala",
355 | ".scm",
356 | ".scss",
357 | ".seestyle",
358 | ".sh",
359 | ".shtml",
360 | ".sln",
361 | ".sls",
362 | ".spec",
363 | ".sql",
364 | ".sqlite",
365 | ".sqlproj",
366 | ".srt",
367 | ".ss",
368 | ".sss",
369 | ".st",
370 | ".strings",
371 | ".sty",
372 | ".styl",
373 | ".stylus",
374 | ".sub",
375 | ".sublime-build",
376 | ".sublime-commands",
377 | ".sublime-completions",
378 | ".sublime-keymap",
379 | ".sublime-macro",
380 | ".sublime-menu",
381 | ".sublime-project",
382 | ".sublime-settings",
383 | ".sublime-workspace",
384 | ".sv",
385 | ".svc",
386 | ".svg",
387 | ".swift",
388 | ".t",
389 | ".tcl",
390 | ".tcsh",
391 | ".terminal",
392 | ".tex",
393 | ".text",
394 | ".textile",
395 | ".tg",
396 | ".tk",
397 | ".tmLanguage",
398 | ".tmpl",
399 | ".tmTheme",
400 | ".tpl",
401 | ".ts",
402 | ".tsv",
403 | ".tsx",
404 | ".tt",
405 | ".tt2",
406 | ".ttml",
407 | ".twig",
408 | ".txt",
409 | ".v",
410 | ".vb",
411 | ".vbproj",
412 | ".vbs",
413 | ".vcproj",
414 | ".vcxproj",
415 | ".vh",
416 | ".vhd",
417 | ".vhdl",
418 | ".vim",
419 | ".viminfo",
420 | ".vimrc",
421 | ".vm",
422 | ".vue",
423 | ".webapp",
424 | ".webmanifest",
425 | ".wsc",
426 | ".x-php",
427 | ".xaml",
428 | ".xht",
429 | ".xhtml",
430 | ".xml",
431 | ".xs",
432 | ".xsd",
433 | ".xsl",
434 | ".xslt",
435 | ".y",
436 | ".yaml",
437 | ".yml",
438 | ".zsh",
439 | ".zshrc"
440 | }
441 | .ToFrozenSet();
442 |
443 | public static IReadOnlyCollection TextExtensions => textExtensions;
444 |
445 | [Obsolete("Use IsTextFile or IsTextExtension")]
446 | public static bool IsText([NotNullWhen(true)] string? extensionOrPath)
447 | {
448 | if (extensionOrPath == null)
449 | {
450 | return false;
451 | }
452 |
453 | if (extensionOrPath.Contains('.') ||
454 | extensionOrPath.Contains(Path.DirectorySeparatorChar) ||
455 | extensionOrPath.Contains(Path.AltDirectorySeparatorChar))
456 | {
457 | var extension = Path.GetExtension(extensionOrPath);
458 | return textExtensions.Contains(extension);
459 | }
460 |
461 | return textExtensions.Contains($".{extensionOrPath}");
462 | }
463 |
464 | [Obsolete("Use IsTextFile or IsTextExtension")]
465 | public static bool IsText(CharSpan extensionOrPath) =>
466 | IsText(extensionOrPath.ToString());
467 | }
--------------------------------------------------------------------------------
/src/EmptyFiles/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using System.Diagnostics.CodeAnalysis;
2 | global using System.Collections.Frozen;
3 | global using System.Text;
--------------------------------------------------------------------------------
/src/EmptyFiles/Guard.cs:
--------------------------------------------------------------------------------
1 | static class Guard
2 | {
3 | public static void FileExists(string path, [CallerArgumentExpression("path")] string argumentName = "")
4 | {
5 | AgainstNullOrEmpty(argumentName, path);
6 | if (!File.Exists(path))
7 | {
8 | throw new ArgumentException($"File not found. Path: {path}");
9 | }
10 | }
11 |
12 | public static void AgainstNullOrEmpty(string value, [CallerArgumentExpression("value")] string argumentName = "")
13 | {
14 | if (string.IsNullOrWhiteSpace(value))
15 | {
16 | throw new ArgumentNullException(argumentName);
17 | }
18 | }
19 |
20 | public static string ValidExtension(string extension, [CallerArgumentExpression(nameof(extension))] string argumentName = "")
21 | {
22 | if (extension.Length == 0)
23 | {
24 | throw new ArgumentNullException(argumentName);
25 | }
26 |
27 | if (extension.StartsWith('.'))
28 | {
29 | return extension;
30 | }
31 |
32 | return $".{extension}";
33 | }
34 | }
--------------------------------------------------------------------------------
/src/EmptyFiles/IsTextFile.cs:
--------------------------------------------------------------------------------
1 | namespace EmptyFiles;
2 |
3 | public delegate bool IsTextFile(CharSpan path);
--------------------------------------------------------------------------------
/src/Shared.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | False
3 | Quiet
4 | True
5 | True
6 | True
7 | DO_NOT_SHOW
8 | ERROR
9 | ERROR
10 | ERROR
11 | WARNING
12 | ERROR
13 | ERROR
14 | ERROR
15 | ERROR
16 | ERROR
17 | ERROR
18 | ERROR
19 | ERROR
20 | ERROR
21 | ERROR
22 | ERROR
23 | ERROR
24 | ERROR
25 | ERROR
26 | ERROR
27 | ERROR
28 | ERROR
29 | ERROR
30 | ERROR
31 | ERROR
32 | ERROR
33 | ERROR
34 | ERROR
35 | ERROR
36 | ERROR
37 | ERROR
38 | ERROR
39 | ERROR
40 | ERROR
41 | ERROR
42 | ERROR
43 | DO_NOT_SHOW
44 | DO_NOT_SHOW
45 | ERROR
46 | ERROR
47 | ERROR
48 | ERROR
49 | ERROR
50 | ERROR
51 | ERROR
52 | ERROR
53 | ERROR
54 | ERROR
55 | ERROR
56 | ERROR
57 | C90+,E79+,S14+
58 | ERROR
59 | ERROR
60 | ERROR
61 | ERROR
62 | ERROR
63 | ERROR
64 | ERROR
65 | ERROR
66 | ERROR
67 | ERROR
68 | ERROR
69 | ERROR
70 | ERROR
71 | ERROR
72 | ERROR
73 | ERROR
74 | ERROR
75 | ERROR
76 | ERROR
77 | ERROR
78 | ERROR
79 | ERROR
80 | ERROR
81 | ERROR
82 | ERROR
83 | ERROR
84 | ERROR
85 | ERROR
86 | ERROR
87 | ERROR
88 | ERROR
89 | ERROR
90 | ERROR
91 | ERROR
92 | ERROR
93 | ERROR
94 | ERROR
95 | ERROR
96 | ERROR
97 | ERROR
98 | ERROR
99 | ERROR
100 | ERROR
101 | ERROR
102 | ERROR
103 | ERROR
104 | ERROR
105 | ERROR
106 | ERROR
107 | ERROR
108 | ERROR
109 | ERROR
110 | ERROR
111 | ERROR
112 | ERROR
113 | ERROR
114 | ERROR
115 | ERROR
116 | ERROR
117 | ERROR
118 | ERROR
119 | ERROR
120 | ERROR
121 | ERROR
122 | DO_NOT_SHOW
123 | *.received.*
124 | *.verified.*
125 | ERROR
126 | ERROR
127 | DO_NOT_SHOW
128 | ECMAScript 2016
129 | <?xml version="1.0" encoding="utf-16"?><Profile name="c# Cleanup"><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><CSCodeStyleAttributes ArrangeVarStyle="True" ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeCodeBodyStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" /><CssAlphabetizeProperties>True</CssAlphabetizeProperties><JSStringLiteralQuotesDescriptor>True</JSStringLiteralQuotesDescriptor><CorrectVariableKindsDescriptor>True</CorrectVariableKindsDescriptor><VariablesToInnerScopesDescriptor>True</VariablesToInnerScopesDescriptor><StringToTemplatesDescriptor>True</StringToTemplatesDescriptor><JsInsertSemicolon>True</JsInsertSemicolon><RemoveRedundantQualifiersTs>True</RemoveRedundantQualifiersTs><OptimizeImportsTs>True</OptimizeImportsTs><OptimizeReferenceCommentsTs>True</OptimizeReferenceCommentsTs><PublicModifierStyleTs>True</PublicModifierStyleTs><ExplicitAnyTs>True</ExplicitAnyTs><TypeAnnotationStyleTs>True</TypeAnnotationStyleTs><RelativePathStyleTs>True</RelativePathStyleTs><AsInsteadOfCastTs>True</AsInsteadOfCastTs><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CssReformatCode>True</CssReformatCode><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><HtmlReformatCode>True</HtmlReformatCode><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags><IDEA_SETTINGS><profile version="1.0">
130 | <option name="myName" value="c# Cleanup" />
131 | </profile></IDEA_SETTINGS><RIDER_SETTINGS><profile>
132 | <Language id="EditorConfig">
133 | <Reformat>false</Reformat>
134 | </Language>
135 | <Language id="HTML">
136 | <OptimizeImports>false</OptimizeImports>
137 | <Reformat>false</Reformat>
138 | <Rearrange>false</Rearrange>
139 | </Language>
140 | <Language id="JSON">
141 | <Reformat>false</Reformat>
142 | </Language>
143 | <Language id="RELAX-NG">
144 | <Reformat>false</Reformat>
145 | </Language>
146 | <Language id="XML">
147 | <OptimizeImports>false</OptimizeImports>
148 | <Reformat>false</Reformat>
149 | <Rearrange>false</Rearrange>
150 | </Language>
151 | </profile></RIDER_SETTINGS></Profile>
152 | ExpressionBody
153 | ExpressionBody
154 | ExpressionBody
155 | False
156 | NEVER
157 | NEVER
158 | False
159 | False
160 | False
161 | True
162 | False
163 | CHOP_ALWAYS
164 | False
165 | False
166 | RemoveIndent
167 | RemoveIndent
168 | False
169 | True
170 | True
171 | True
172 | True
173 | True
174 | ERROR
175 | DoNothing
176 |
--------------------------------------------------------------------------------
/src/Tests/ContentTypesTests.cs:
--------------------------------------------------------------------------------
1 | public class ContentTypesTests
2 | {
3 | [Test]
4 | public void TryGetExtension()
5 | {
6 | True(ContentTypes.TryGetExtension("application/json", out var extension));
7 | AreEqual("json", extension);
8 | True(ContentTypes.TryGetExtension("foo/bar+json", out extension));
9 | AreEqual("json", extension);
10 | True(ContentTypes.TryGetExtension("text/html; charset=utf-8", out extension));
11 | AreEqual("html", extension);
12 | True(ContentTypes.TryGetExtension("foo/bin", out extension));
13 | AreEqual("bin", extension);
14 | }
15 |
16 | [Test]
17 | public void IsText()
18 | {
19 | True(ContentTypes.IsText("application/json", out var extension));
20 | AreEqual("json", extension);
21 | True(ContentTypes.IsText("text/html; charset=utf-8", out extension));
22 | AreEqual("html", extension);
23 | True(ContentTypes.IsText("foo/bar+json", out extension));
24 | AreEqual("json", extension);
25 | False(ContentTypes.IsText("foo/bin", out extension));
26 |
27 | True(ContentTypes.IsText("application/json"));
28 | True(ContentTypes.IsText("foo/bar+json"));
29 | False(ContentTypes.IsText("foo/bin"));
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Tests/ExtensionsTests.cs:
--------------------------------------------------------------------------------
1 | public class ExtensionsTests
2 | {
3 | [Test]
4 | public void IsText()
5 | {
6 | #region IsText
7 |
8 | True(FileExtensions.IsTextFile("file.txt"));
9 | False(FileExtensions.IsTextFile("file.bin"));
10 | True(FileExtensions.IsTextExtension(".txt"));
11 | False(FileExtensions.IsTextExtension(".bin"));
12 | True(FileExtensions.IsTextExtension("txt"));
13 | False(FileExtensions.IsTextExtension("bin"));
14 |
15 | #endregion
16 |
17 | False(FileExtensions.IsTextFile(".StartingWithDot"));
18 | False(FileExtensions.IsTextFile("NoExtension"));
19 |
20 | #region TextViaConvention
21 |
22 | True(FileExtensions.IsTextFile("c:/path/file.txtViaConvention"));
23 |
24 | #endregion
25 | }
26 |
27 | #region AddTextFileConvention
28 | [ModuleInitializer]
29 | public static void AddTextFileConvention() =>
30 | // Treat files ending with .txtViaConvention as text files
31 | FileExtensions.AddTextFileConvention(path => path.EndsWith(".txtViaConvention"));
32 |
33 | #endregion
34 |
35 | [Test]
36 | public void IsTextLegacy()
37 | {
38 | #pragma warning disable CS0618 // Type or member is obsolete
39 | True(FileExtensions.IsText("file.txt"));
40 | False(FileExtensions.IsText("file.bin"));
41 | True(FileExtensions.IsText("c:/file.txt"));
42 | False(FileExtensions.IsText("c:/file.bin"));
43 | True(FileExtensions.IsText(".txt"));
44 | True(FileExtensions.IsText("txt"));
45 | False(FileExtensions.IsText(".bin"));
46 | False(FileExtensions.IsText("bin"));
47 | #pragma warning restore CS0618 // Type or member is obsolete
48 | }
49 |
50 | [Test]
51 | public void AddTextExtension()
52 | {
53 | #region AddTextExtension
54 |
55 | FileExtensions.AddTextExtension(".ext1");
56 | True(FileExtensions.IsTextExtension(".ext1"));
57 | True(FileExtensions.IsTextFile("file.ext1"));
58 |
59 | #endregion
60 |
61 | FileExtensions.AddTextExtension("ext2");
62 | True(FileExtensions.IsTextExtension("ext2"));
63 | True(FileExtensions.IsTextFile("file.ext2"));
64 | }
65 |
66 | [Test]
67 | public void RemoveTextExtension()
68 | {
69 | #region RemoveTextExtension
70 |
71 | FileExtensions.AddTextExtension(".ext1");
72 | True(FileExtensions.IsTextExtension(".ext1"));
73 | FileExtensions.RemoveTextExtension(".ext1");
74 | False(FileExtensions.IsTextExtension(".ext1"));
75 |
76 | #endregion
77 |
78 | FileExtensions.AddTextExtension("ext1");
79 | True(FileExtensions.IsTextExtension("ext1"));
80 | FileExtensions.RemoveTextExtension("ext1");
81 | False(FileExtensions.IsTextExtension("ext1"));
82 | }
83 | }
--------------------------------------------------------------------------------
/src/Tests/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using EmptyFiles;
2 | global using NUnit.Framework;
3 | global using System.Collections.Immutable;
--------------------------------------------------------------------------------
/src/Tests/ImmutableVersionTests.cs:
--------------------------------------------------------------------------------
1 | #if NETFRAMEWORK
2 |
3 | public class ImmutableVersionTests
4 | {
5 | // work around https://github.com/orgs/VerifyTests/discussions/1366
6 | [Test]
7 | public void AssertVersion()
8 | {
9 | var assemblyName = typeof(ImmutableDictionary).Assembly.GetName();
10 | AreEqual(new Version(8, 0, 0, 0), assemblyName.Version);
11 | }
12 | }
13 |
14 | #endif
--------------------------------------------------------------------------------
/src/Tests/IndexWriter.cs:
--------------------------------------------------------------------------------
1 | #if NET9_0
2 | public class IndexWriter
3 | {
4 | static List> files = null!;
5 |
6 | [ModuleInitializer]
7 | public static void Init() =>
8 | files = AllFiles
9 | .Files.OrderBy(_ => _.Key)
10 | .ToList();
11 | [Test]
12 | public void CreateIndex() =>
13 | InnerCreateIndex();
14 |
15 | static void InnerCreateIndex([CallerFilePath] string filePath = "")
16 | {
17 | var rootDirectory = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(filePath)!, @"..\..\"));
18 | var indexPath = Path.Combine(rootDirectory, "index");
19 | Directory.CreateDirectory(indexPath);
20 | foreach (var toDelete in Directory.EnumerateFiles(indexPath))
21 | {
22 | File.Delete(toDelete);
23 | }
24 |
25 | foreach (var (key, value) in files)
26 | {
27 | File.Copy(value.Path, Path.Combine(indexPath, $"empty{key}"));
28 | }
29 | }
30 | }
31 | #endif
--------------------------------------------------------------------------------
/src/Tests/Size.cs:
--------------------------------------------------------------------------------
1 | static class Size
2 | {
3 | static string[] SizeSuffixes =
4 | [
5 | "bytes",
6 | "KB",
7 | "MB"
8 | ];
9 |
10 | public static string Suffix(long value)
11 | {
12 | var mag = (int) Math.Log(value, 1024);
13 |
14 | var adjustedSize = (decimal) value / (1L << (mag * 10));
15 |
16 | if (Math.Round(adjustedSize, 1) >= 1000)
17 | {
18 | mag += 1;
19 | adjustedSize /= 1024;
20 | }
21 |
22 | return $"{adjustedSize:0.#} {SizeSuffixes[mag]}";
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Tests/SolutionDirectoryFinder.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 |
3 | static class SolutionDirectoryFinder
4 | {
5 | public static string Find([CallerFilePath] string testFile = "")
6 | {
7 | var testDirectory = Path.GetDirectoryName(testFile)!;
8 | if (!TryFind(testDirectory, out var solutionDirectory))
9 | {
10 | throw new("Could not find solution directory");
11 | }
12 |
13 | return solutionDirectory;
14 | }
15 |
16 | public static bool TryFind(string testDirectory, [NotNullWhen(true)] out string? path)
17 | {
18 | var currentDirectory = testDirectory;
19 | do
20 | {
21 | if (Directory
22 | .GetFiles(currentDirectory, "*.sln").Length != 0)
23 | {
24 | path = currentDirectory;
25 | return true;
26 | }
27 |
28 | var parent = Directory.GetParent(currentDirectory);
29 | if (parent == null)
30 | {
31 | path = null;
32 | return false;
33 | }
34 |
35 | currentDirectory = parent.FullName;
36 | } while (true);
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Tests/Tests.cs:
--------------------------------------------------------------------------------
1 | public class Tests
2 | {
3 | [Test]
4 | public void CreateFile_overwrite_binary()
5 | {
6 | AllFiles.CreateFile("foo.bmp");
7 | AllFiles.CreateFile("foo.bmp");
8 | True(File.Exists("foo.bmp"));
9 | }
10 |
11 | [Test]
12 | public void CreateFile_NoDir_binary()
13 | {
14 | if (Directory.Exists("myTempDir"))
15 | {
16 | Directory.Delete("myTempDir", true);
17 | }
18 |
19 | AllFiles.CreateFile("myTempDir/foo.bmp");
20 | True(File.Exists("myTempDir/foo.bmp"));
21 | }
22 |
23 | [Test]
24 | public void CreateFile_preamble()
25 | {
26 | AllFiles.CreateFile("foo.txt", true);
27 |
28 | var preamble = Encoding.UTF8.GetPreamble();
29 | var bytes = File.ReadAllBytes("foo.txt");
30 | if (bytes.Length < preamble.Length ||
31 | preamble
32 | .Where((p, i) => p != bytes[i])
33 | .Any())
34 | {
35 | throw new ArgumentException("Not utf8-BOM");
36 | }
37 | }
38 |
39 | [Test]
40 | public void CreateFile_overwrite_txt()
41 | {
42 | AllFiles.CreateFile("foo.txt", true);
43 | AllFiles.CreateFile("foo.txt", true);
44 | True(File.Exists("foo.txt"));
45 | }
46 |
47 | [Test]
48 | public void CreateFile_NoDir_txt()
49 | {
50 | if (Directory.Exists("myTempDir"))
51 | {
52 | Directory.Delete("myTempDir", true);
53 | }
54 |
55 | AllFiles.CreateFile("myTempDir/foo.txt", true);
56 | True(File.Exists("myTempDir/foo.txt"));
57 | }
58 |
59 | [Test]
60 | public void TryCreateFile_overwrite_txt()
61 | {
62 | True(AllFiles.TryCreateFile("foo.txt", true));
63 | True(AllFiles.TryCreateFile("foo.txt", true));
64 | True(File.Exists("foo.txt"));
65 | }
66 |
67 | [Test]
68 | public void TryCreateFile_NoDir_txt()
69 | {
70 | if (Directory.Exists("myTempDir"))
71 | {
72 | Directory.Delete("myTempDir", true);
73 | }
74 |
75 | True(AllFiles.TryCreateFile("myTempDir/foo.txt", true));
76 | True(File.Exists("myTempDir/foo.txt"));
77 | }
78 |
79 | [Test]
80 | public void TryCreateFile_overwrite_binary()
81 | {
82 | True(AllFiles.TryCreateFile("foo.bmp"));
83 | True(AllFiles.TryCreateFile("foo.bmp"));
84 | True(File.Exists("foo.bmp"));
85 | }
86 |
87 | [Test]
88 | public void TryCreateFile_NoDir_binary()
89 | {
90 | if (Directory.Exists("myTempDir"))
91 | {
92 | Directory.Delete("myTempDir", true);
93 | }
94 |
95 | True(AllFiles.TryCreateFile("myTempDir/foo.bmp"));
96 | True(File.Exists("myTempDir/foo.bmp"));
97 | }
98 |
99 | [Test]
100 | public void Unknown_extension()
101 | {
102 | Throws(() => AllFiles.GetPathFor("txt"));
103 | False(AllFiles.TryGetPathFor("txt", out var result));
104 | Null(result);
105 | False(AllFiles.TryGetPathFor(".txt", out result));
106 | Null(result);
107 | False(AllFiles.TryCreateFile("foo.txt"));
108 | Null(result);
109 | Throws(() => AllFiles.GetPathFor(".txt"));
110 | Throws(() => AllFiles.CreateFile("foo.txt"));
111 | }
112 |
113 | [Test]
114 | public void GetPathFor()
115 | {
116 | #region GetPathFor
117 |
118 | var path = AllFiles.GetPathFor(".jpg");
119 |
120 | #endregion
121 |
122 | NotNull(path);
123 | True(File.Exists(path));
124 |
125 | path = AllFiles.GetPathFor("jpg");
126 | NotNull(path);
127 | True(File.Exists(path));
128 | }
129 |
130 | [Test]
131 | public void CreateFile()
132 | {
133 | var pathOfFileToCreate = "file.jpg";
134 | File.Delete(pathOfFileToCreate);
135 |
136 | #region CreateFile
137 |
138 | AllFiles.CreateFile(pathOfFileToCreate);
139 |
140 | #endregion
141 |
142 | True(File.Exists(pathOfFileToCreate));
143 | File.Delete(pathOfFileToCreate);
144 |
145 | AllFiles.CreateFile("foo.txt", true);
146 | True(File.Exists("foo.txt"));
147 | File.Delete("foo.txt");
148 |
149 | True(AllFiles.TryCreateFile(pathOfFileToCreate));
150 | True(File.Exists(pathOfFileToCreate));
151 | File.Delete(pathOfFileToCreate);
152 |
153 | False(AllFiles.TryCreateFile("foo.txt"));
154 | False(File.Exists("foo.txt"));
155 | File.Delete("foo.txt");
156 |
157 | True(AllFiles.TryCreateFile("foo.txt", true));
158 | True(File.Exists("foo.txt"));
159 | File.Delete("foo.txt");
160 | }
161 |
162 | [Test]
163 | public void IsEmptyFile()
164 | {
165 | #region IsEmptyFile
166 |
167 | var path = AllFiles.GetPathFor(".jpg");
168 | True(AllFiles.IsEmptyFile(path));
169 | var temp = Path.GetTempFileName();
170 | False(AllFiles.IsEmptyFile(temp));
171 |
172 | #endregion
173 |
174 | File.Delete(temp);
175 | }
176 |
177 | [Test]
178 | public void AllPaths()
179 | {
180 | IsNotEmpty(AllFiles.AllPaths);
181 |
182 | #region AllPaths
183 |
184 | foreach (var path in AllFiles.AllPaths)
185 | {
186 | Trace.WriteLine(path);
187 | }
188 |
189 | #endregion
190 | }
191 |
192 | static string ThisFile([CallerFilePath] string testFile = "") =>
193 | testFile;
194 |
195 | //[Test]
196 | #pragma warning disable CA1822
197 | public void UseFile()
198 | #pragma warning restore CA1822
199 | {
200 | var pathToFile = ThisFile();
201 |
202 | #region UseFile
203 |
204 | AllFiles.UseFile(Category.Document, pathToFile);
205 | IsTrue(AllFiles.DocumentPaths.Contains(pathToFile));
206 |
207 | #endregion
208 | }
209 |
210 | #if NET9_0
211 |
212 | [Test]
213 | public async Task WriteExtensions()
214 | {
215 | var md = Path.Combine(SolutionDirectoryFinder.Find(), "extensions.include.md");
216 | File.Delete(md);
217 | await using var writer = File.CreateText(md);
218 | await WriteCategory(writer, "Archive", AllFiles.Archives);
219 | await WriteCategory(writer, "Document", AllFiles.Documents);
220 | await WriteCategory(writer, "Image", AllFiles.Images);
221 | await WriteCategory(writer, "Sheet", AllFiles.Sheets);
222 | await WriteCategory(writer, "Slide", AllFiles.Slides);
223 | }
224 |
225 | #endif
226 |
227 | static async Task WriteCategory(StreamWriter writer, string category, IReadOnlyDictionary files)
228 | {
229 | await writer.WriteLineAsync("");
230 | await writer.WriteLineAsync($"### {category}");
231 | await writer.WriteLineAsync("");
232 | foreach (var file in files.OrderBy(_ => _.Key))
233 | {
234 | var size = Size.Suffix(new FileInfo(file.Value.Path).Length);
235 | await writer.WriteLineAsync($" * {file.Key} ({size})");
236 | }
237 | }
238 | }
--------------------------------------------------------------------------------
/src/Tests/Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net48
5 | net8.0;net9.0;$(TargetFrameworks)
6 | true
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/appveyor.yml:
--------------------------------------------------------------------------------
1 | image:
2 | - Visual Studio 2022
3 | - macOS
4 | # - Ubuntu
5 | environment:
6 | DOTNET_NOLOGO: true
7 | DOTNET_CLI_TELEMETRY_OPTOUT: true
8 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
9 | build_script:
10 | - pwsh: |
11 | if ($isWindows) {
12 | Invoke-WebRequest "https://dot.net/v1/dotnet-install.ps1" -OutFile "./dotnet-install.ps1"
13 | ./dotnet-install.ps1 -JSonFile src/global.json -Architecture x64 -InstallDir 'C:\Program Files\dotnet'
14 | }
15 | if ($isMacOS) {
16 | Invoke-WebRequest "https://dot.net/v1/dotnet-install.sh" -OutFile "./dotnet-install.sh"
17 | sudo chmod u+x dotnet-install.sh
18 | sudo ./dotnet-install.sh --jsonfile src/global.json --architecture x64 --install-dir '/usr/local/share/dotnet'
19 | }
20 | if ($isLinux) {
21 | Invoke-WebRequest "https://dot.net/v1/dotnet-install.sh" -OutFile "./dotnet-install.sh"
22 | sudo chmod u+x dotnet-install.sh
23 | sudo ./dotnet-install.sh --jsonfile src/global.json --architecture x64 --install-dir '/usr/share/dotnet'
24 | }
25 | - dotnet build src --configuration Release
26 | - dotnet test src --configuration Release --no-build --no-restore
27 | test: off
28 | artifacts:
29 | - path: nugets\*.nupkg
--------------------------------------------------------------------------------
/src/extensions.include.md:
--------------------------------------------------------------------------------
1 |
2 | ### Archive
3 |
4 | * .7z (32 bytes)
5 | * .7zip (32 bytes)
6 | * .bz2 (14 bytes)
7 | * .bzip2 (14 bytes)
8 | * .gz (29 bytes)
9 | * .gzip (29 bytes)
10 | * .tar (1.5 KB)
11 | * .xz (32 bytes)
12 | * .zip (22 bytes)
13 |
14 | ### Document
15 |
16 | * .docx (1.9 KB)
17 | * .odt (2.2 KB)
18 | * .pdf (280 bytes)
19 | * .rtf (6 bytes)
20 |
21 | ### Image
22 |
23 | * .avif (298 bytes)
24 | * .bmp (58 bytes)
25 | * .dds (136 bytes)
26 | * .dib (58 bytes)
27 | * .emf (620 bytes)
28 | * .exif (734 bytes)
29 | * .gif (799 bytes)
30 | * .heic (3.2 KB)
31 | * .heif (209 bytes)
32 | * .ico (70 bytes)
33 | * .j2c (270 bytes)
34 | * .jfif (734 bytes)
35 | * .jp2 (354 bytes)
36 | * .jpc (270 bytes)
37 | * .jpe (734 bytes)
38 | * .jpeg (734 bytes)
39 | * .jpg (734 bytes)
40 | * .jxr (300 bytes)
41 | * .pbm (8 bytes)
42 | * .pcx (131 bytes)
43 | * .pgm (12 bytes)
44 | * .png (119 bytes)
45 | * .ppm (14 bytes)
46 | * .rle (58 bytes)
47 | * .tga (543 bytes)
48 | * .tif (250 bytes)
49 | * .tiff (250 bytes)
50 | * .wdp (300 bytes)
51 | * .webp (228 bytes)
52 | * .wmp (300 bytes)
53 |
54 | ### Sheet
55 |
56 | * .ods (2.7 KB)
57 | * .xlsx (4.5 KB)
58 |
59 | ### Slide
60 |
61 | * .odp (7.8 KB)
62 | * .pptx (13.3 KB)
63 |
--------------------------------------------------------------------------------
/src/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "9.0.300",
4 | "allowPrerelease": true,
5 | "rollForward": "latestFeature"
6 | }
7 | }
--------------------------------------------------------------------------------
/src/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/src/icon.png
--------------------------------------------------------------------------------
/src/key.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VerifyTests/EmptyFiles/011043df36949534b5e1f54dc36e075e165bc257/src/key.snk
--------------------------------------------------------------------------------
/src/mdsnippets.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/SimonCropp/MarkdownSnippets/master/schema.json",
3 | "TocExcludes": [ "NuGet package", "Release Notes", "Icon" ],
4 | "MaxWidth": 100,
5 | "Convention": "InPlaceOverwrite"
6 | }
--------------------------------------------------------------------------------
/src/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
20 |
21 |
24 |
25 |
26 |
--------------------------------------------------------------------------------