Thank you for your interest in contributing to PawSharp! This document outlines guidelines, best practices, and development workflows for contributing code, documentation, and ideas to the project.
- .NET 10.0 SDK or later
- Git
- IDE: Visual Studio 2022, VS Code, or Rider
- Fork the repository on GitHub
- Clone your fork:
git clone https://github.com/your-username/PawSharp.git cd PawSharp - Add upstream remote:
git remote add upstream https://github.com/original-owner/PawSharp.git
- Create a feature branch:
git checkout -b feature/your-feature-name
- Build the solution:
dotnet build
- Run tests:
dotnet test
- Follow the provided
.editorconfigfile - Use meaningful variable and method names
- Keep methods focused on single responsibilities
- Prefer async/await over synchronous operations
- Use
varwhen the type is obvious
- Always throw exceptions instead of returning null/empty collections
- Use dependency injection for all services and components
- Implement proper logging with structured logging
- Add XML documentation to all public APIs
- Write comprehensive unit tests for new features
- Handle errors gracefully with typed exceptions
src/
├── PawSharp.Core/ # Core entities, exceptions, validation
├── PawSharp.API/ # REST client and rate limiting
├── PawSharp.Gateway/ # WebSocket gateway and events
├── PawSharp.Cache/ # Caching providers
├── PawSharp.Client/ # High-level client
├── PawSharp.Interactions/ # Slash commands and components
├── PawSharp.Commands/ # Command framework
├── PawSharp.Interactivity/ # Interactive features
└── PawSharp.Voice/ # Voice support (experimental)
- Check GitHub Issues for open tasks
- Look for "good first issue" or "help wanted" labels
- Comment on the issue to indicate you're working on it
- Write clean, testable code
- Add unit tests for new functionality
- Update documentation as needed
- Ensure all tests pass:
dotnet test
- Unit Tests: Test individual components in isolation
- Integration Tests: Test component interactions
- Manual Testing: Test with a real Discord bot
- Performance Testing: Use benchmarks for performance-critical code
- Update XML comments for public APIs
- Add examples for new features
- Update README and docs as needed
- Ensure code samples compile and work
git add .
git commit -m "feat: add new feature
- Description of changes
- Related issue: #123"
git push origin feature/your-feature-name- Use a descriptive title and detailed description
- Reference related issues
- Request review from maintainers
- Address review feedback
All components should support DI:
// ✅ Good
public class MyService
{
private readonly ILogger<MyService> _logger;
private readonly ICacheProvider _cache;
public MyService(ILogger<MyService> logger, ICacheProvider cache)
{
_logger = logger;
_cache = cache;
}
}Use typed exceptions and handle them appropriately:
// ✅ Good
public async Task SendMessageAsync(ulong channelId, string content)
{
if (string.IsNullOrWhiteSpace(content))
throw new ValidationException("Content cannot be empty");
if (content.Length > 2000)
throw new ValidationException("Content exceeds 2000 characters");
// Implementation
}Use structured logging with appropriate levels:
// ✅ Good
_logger.LogInformation("Bot connected to {GuildCount} guilds", guilds.Count);
_logger.LogWarning("Rate limit hit for endpoint {Endpoint}, retrying in {RetryAfter}s",
endpoint, retryAfter);
_logger.LogError(ex, "Failed to process message {MessageId}", messageId);All I/O operations should be async:
// ✅ Good
public async Task<Message> SendMessageAsync(CreateMessageRequest request)
{
var response = await _httpClient.PostAsync(endpoint, content);
return await DeserializeAsync<Message>(response);
}
// ❌ Bad
public Message SendMessage(CreateMessageRequest request)
{
var response = _httpClient.PostAsync(endpoint, content).Result;
return Deserialize<Message>(response.Result);
}- Test public APIs and error conditions
- Use mocking for external dependencies
- Follow AAA pattern (Arrange, Act, Assert)
- Name tests descriptively:
MethodName_Condition_ExpectedResult
[Fact]
public async Task CreateMessageAsync_ValidRequest_ReturnsMessage()
{
// Arrange
var request = new CreateMessageRequest { Content = "Test" };
var mockRestClient = new Mock<IDiscordRestClient>();
mockRestClient.Setup(x => x.CreateMessageAsync(It.IsAny<ulong>(), It.IsAny<CreateMessageRequest>()))
.ReturnsAsync(new Message { Id = 123, Content = "Test" });
// Act
var result = await mockRestClient.Object.CreateMessageAsync(456, request);
// Assert
Assert.NotNull(result);
Assert.Equal("Test", result.Content);
}- Test real component interactions
- Use test databases/cache providers
- Clean up after tests
/// <summary>
/// Sends a message to a Discord channel.
/// </summary>
/// <param name="channelId">The ID of the channel to send to.</param>
/// <param name="request">The message creation request.</param>
/// <returns>The created message.</returns>
/// <exception cref="ValidationException">Thrown when request is invalid.</exception>
/// <exception cref="RateLimitException">Thrown when rate limited.</exception>
public async Task<Message> CreateMessageAsync(ulong channelId, CreateMessageRequest request)- Keep installation instructions current
- Update feature lists for new capabilities
- Add migration notes for breaking changes
- Caching: Use appropriate cache strategies
- Memory Management: Avoid memory leaks in long-running bots
- Rate Limiting: Respect Discord's limits and implement backoff
- Concurrency: Use thread-safe collections and proper locking
- Serialization: Optimize JSON serialization for large payloads
- Token Handling: Never log or expose bot tokens
- Input Validation: Validate all user input before processing
- Permission Checks: Verify bot permissions before API calls
- Error Messages: Don't expose sensitive information in errors
- Dependencies: Keep NuGet packages updated and secure
PawSharp follows Semantic Versioning:
- MAJOR: Breaking changes
- MINOR: New features (backward compatible)
- PATCH: Bug fixes (backward compatible)
- Use pre-release tags:
1.0.0-alpha1,1.0.0-beta1 - Clearly document experimental features
- Provide migration guides for breaking changes
- Issues: For bugs and feature requests
- Discussions: For questions and ideas
- Discord: Community chat (link coming soon)
- Documentation: Check docs/ and examples/
Contributors are recognized in:
- CHANGELOG.md for significant contributions
- GitHub's contributor insights
- Future contributor acknowledgments
We appreciate your help in making PawSharp better for everyone! Happy coding! 🚀