|
| 1 | +# System.IO.Abstractions Development Guide |
| 2 | + |
| 3 | +System.IO.Abstractions is a .NET library that provides testable abstractions for System.IO operations, enabling developers to write unit tests that don't rely on the actual file system. |
| 4 | + |
| 5 | +**ALWAYS reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.** |
| 6 | + |
| 7 | +## Working Effectively |
| 8 | + |
| 9 | +### Bootstrap and Build Process |
| 10 | +- **CRITICAL**: Install .NET SDK 9.0.304 (required version specified in global.json): |
| 11 | + ```bash |
| 12 | + curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --version 9.0.304 |
| 13 | + export PATH="$HOME/.dotnet:$PATH" |
| 14 | + ``` |
| 15 | +- Verify installation: `dotnet --version` should return `9.0.304` |
| 16 | +- **Build the solution**: `dotnet build` -- takes ~70 seconds. NEVER CANCEL. Set timeout to 120+ minutes. |
| 17 | +- **Run all tests**: `dotnet test --configuration Release` -- takes ~30 seconds. NEVER CANCEL. Set timeout to 60+ minutes. |
| 18 | + |
| 19 | +### Code Quality and Formatting |
| 20 | +- **ALWAYS run code formatting before committing**: `dotnet format` |
| 21 | +- **Verify formatting compliance**: `dotnet format --verify-no-changes` -- takes ~40 seconds. NEVER CANCEL. |
| 22 | +- The codebase uses EditorConfig with CRLF line endings and 4-space indentation for C# files |
| 23 | +- **CRITICAL**: All formatting issues must be resolved before CI will pass |
| 24 | + |
| 25 | +### Build System Details |
| 26 | +- **Primary build method**: `dotnet build` and `dotnet test` commands work reliably |
| 27 | +- **NUKE build script**: `./build.sh` available but may have GitVersion issues with shallow clones |
| 28 | +- **Available NUKE targets**: UnitTests, ApiChecks, CodeCoverage, CodeAnalysis, Pack |
| 29 | +- **Build artifacts**: Generated in `Artifacts/` and `TestResults/` directories |
| 30 | + |
| 31 | +## Project Structure |
| 32 | + |
| 33 | +### Key Projects |
| 34 | +- **System.IO.Abstractions**: Core abstractions and interfaces |
| 35 | +- **TestableIO.System.IO.Abstractions**: Main implementation |
| 36 | +- **TestableIO.System.IO.Abstractions.Wrappers**: Wrapper implementations |
| 37 | +- **TestableIO.System.IO.Abstractions.TestingHelpers**: Mock implementations for testing |
| 38 | +- **Multiple test projects**: Comprehensive test coverage across different scenarios |
| 39 | + |
| 40 | +### Target Frameworks |
| 41 | +- .NET Framework 4.7.2 (net472) |
| 42 | +- .NET Standard 2.0, 2.1 (netstandard2.0, netstandard2.1) |
| 43 | +- .NET 6.0, 8.0, 9.0 (net6.0, net8.0, net9.0) |
| 44 | + |
| 45 | +### Important Directories |
| 46 | +- `src/`: All source code projects |
| 47 | +- `tests/`: All test projects including unit tests, API tests, and parity tests |
| 48 | +- `benchmarks/`: Performance benchmarking projects |
| 49 | +- `Pipeline/`: NUKE build system configuration |
| 50 | +- `.github/workflows/`: CI/CD pipeline definitions |
| 51 | + |
| 52 | +## Validation |
| 53 | + |
| 54 | +### Manual Validation Steps |
| 55 | +After making changes, ALWAYS validate functionality by: |
| 56 | + |
| 57 | +1. **Build verification**: `dotnet build` must succeed |
| 58 | +2. **Test execution**: `dotnet test --configuration Release` must pass |
| 59 | +3. **Code formatting**: `dotnet format --verify-no-changes` must pass |
| 60 | +4. **Functional validation**: Create a test scenario to verify your changes work: |
| 61 | + |
| 62 | +```csharp |
| 63 | +using System.IO.Abstractions; |
| 64 | +using System.IO.Abstractions.TestingHelpers; |
| 65 | + |
| 66 | +// Test MockFileSystem functionality |
| 67 | +var mockFileSystem = new MockFileSystem(); |
| 68 | +mockFileSystem.File.WriteAllText(@"C:\test.txt", "Test content"); |
| 69 | +var content = mockFileSystem.File.ReadAllText(@"C:\test.txt"); |
| 70 | + |
| 71 | +// Test real FileSystem functionality |
| 72 | +var realFileSystem = new FileSystem(); |
| 73 | +var tempFile = "/tmp/test.txt"; |
| 74 | +realFileSystem.File.WriteAllText(tempFile, "Real test"); |
| 75 | +var realContent = realFileSystem.File.ReadAllText(tempFile); |
| 76 | +realFileSystem.File.Delete(tempFile); |
| 77 | +``` |
| 78 | + |
| 79 | +### Test Suite Information |
| 80 | +- **Total tests**: ~2,234 tests across all projects |
| 81 | +- **Expected passing**: ~1,993 tests (some platform-specific tests are skipped on Linux) |
| 82 | +- **Test categories**: Unit tests, API compatibility tests, parity tests |
| 83 | +- **Platform considerations**: Some Windows-specific functionality is skipped on Linux/macOS |
| 84 | + |
| 85 | +### Continuous Integration Requirements |
| 86 | +The CI pipeline (.github/workflows/ci.yml) requires: |
| 87 | +- All unit tests to pass on Ubuntu, Windows, and macOS |
| 88 | +- API compatibility checks to succeed |
| 89 | +- Code formatting compliance |
| 90 | +- Static code analysis (SonarCloud) to pass |
| 91 | + |
| 92 | +## Common Development Tasks |
| 93 | + |
| 94 | +### Adding New Functionality |
| 95 | +- Implement abstractions in the main System.IO.Abstractions project |
| 96 | +- Add wrapper implementations in TestableIO.System.IO.Abstractions.Wrappers |
| 97 | +- Create mock implementations in TestableIO.System.IO.Abstractions.TestingHelpers |
| 98 | +- Add comprehensive tests covering all target frameworks |
| 99 | +- Update XML documentation for all public APIs |
| 100 | + |
| 101 | +### Debugging Build Issues |
| 102 | +- Check .NET SDK version compatibility first |
| 103 | +- Verify all package references are properly restored |
| 104 | +- For NUKE build issues, use direct `dotnet` commands instead |
| 105 | +- Review build logs in Artifacts/ directory for detailed error information |
| 106 | + |
| 107 | +### Package Management |
| 108 | +- Uses Central Package Management (Directory.Packages.props) |
| 109 | +- NuGet source: nuget.org only (configured in nuget.config) |
| 110 | +- Package versioning uses Nerdbank.GitVersioning |
| 111 | + |
| 112 | +## Pull Request Guidelines |
| 113 | + |
| 114 | +### Pull Request Title |
| 115 | +To communicate intent to the consumers of your library, the title of the pull requests is prefixed with one of the following elements: |
| 116 | +- `fix:`: patches a bug |
| 117 | +- `feat:`: introduces a new feature |
| 118 | +- `refactor:`: improves internal structure without changing the observable behavior |
| 119 | +- `docs:`: updates documentation or XML comments |
| 120 | +- `chore:`: updates to dependencies, build pipelines, ... |
| 121 | + |
| 122 | +## Performance Expectations |
| 123 | + |
| 124 | +### Command Timing (with appropriate timeouts) |
| 125 | +- **dotnet build**: ~70 seconds (set timeout: 120+ minutes) |
| 126 | +- **dotnet test**: ~30 seconds (set timeout: 60+ minutes) |
| 127 | +- **dotnet format**: ~40 seconds (set timeout: 10+ minutes) |
| 128 | +- **NUKE build restore**: ~30 seconds (set timeout: 10+ minutes) |
| 129 | + |
| 130 | +### **NEVER CANCEL** long-running operations |
| 131 | +Builds and tests may occasionally take longer than expected. Always wait for completion rather than canceling operations. |
| 132 | + |
| 133 | +## Troubleshooting |
| 134 | + |
| 135 | +### Common Issues |
| 136 | +- **GitVersion errors**: Use direct `dotnet` commands instead of NUKE build script |
| 137 | +- **Shallow clone issues**: Expected in GitHub Actions environment, doesn't affect functionality |
| 138 | +- **Platform-specific test failures**: Normal for Windows-specific functionality on Linux/macOS |
| 139 | +- **Code formatting failures**: Run `dotnet format` to fix automatically |
| 140 | + |
| 141 | +### SDK Installation Issues |
| 142 | +If .NET SDK 9.0.304 is not available: |
| 143 | +- Check global.json for exact version requirement |
| 144 | +- Use dotnet-install script with specific version |
| 145 | +- Ensure PATH includes the installed SDK location |
| 146 | + |
| 147 | +**Remember**: This is a mature, well-tested library with extensive CI/CD. Focus on maintaining compatibility across all target frameworks and ensuring comprehensive test coverage for any changes. |
0 commit comments