Thank you for your interest in contributing to jcurses! This document provides guidelines and instructions for contributing.
- Code of Conduct
- Getting Started
- Development Setup
- How to Contribute
- Pull Request Process
- Code Style
- Testing
- Documentation
- Be respectful and inclusive
- Focus on constructive feedback
- Help others learn and grow
- Follow the project's technical standards
- Fork the repository on GitHub
- Clone your fork locally:
git clone git@github.com:YOUR_USERNAME/jcurses.git cd jcurses - Add upstream remote:
git remote add upstream git@github.com:FlossWare/jcurses.git
- Java 21+ with preview features enabled
- Maven 3.8+
- ncurses library (Linux/macOS) or PDCurses (Windows)
Linux (Fedora/RHEL/CentOS):
sudo dnf install ncurses-develLinux (Debian/Ubuntu):
sudo apt-get install libncurses5-devmacOS:
brew install ncursesWindows:
- Install PDCurses or use WSL with Linux ncurses
# Build the project
mvn clean install
# Run tests
mvn test
# Run with coverage
mvn clean test jacoco:report
# View coverage report
open target/site/jacoco/index.html
# Run interactive demo
./run-interactive.sh # Linux/macOS
run-interactive.bat # Windows CMD- Bug Fixes: Fix existing bugs or issues
- New Features: Add new widgets, layouts, or functionality
- Documentation: Improve README, JavaDoc, or guides
- Tests: Add or improve test coverage
- Performance: Optimize rendering or memory usage
- Refactoring: Improve code quality without changing behavior
- Check existing issues to avoid duplicate work
- Open an issue to discuss major changes before implementing
- Keep changes focused - one feature or fix per PR
- Write tests for new functionality
git checkout -b feature/my-feature-name
# or
git checkout -b fix/issue-number-description- Write clean, readable code
- Follow existing code style
- Add tests for new functionality
- Update documentation as needed
# Run all tests
mvn test
# Run specific test class
mvn test -Dtest=JButtonTest
# Run interactive demo to verify visually
./run-interactive.shUse conventional commit messages:
git commit -m "feat: add new widget JTreeView"
git commit -m "fix: correct mouse event coordinates"
git commit -m "docs: update README with new examples"
git commit -m "test: add edge cases for JTextField"
git commit -m "refactor: extract layout calculation logic"Commit Message Format:
feat:New featurefix:Bug fixdocs:Documentation changestest:Test additions or modificationsrefactor:Code refactoringperf:Performance improvementschore:Build/tooling changes
git push origin feature/my-feature-name- Provide a clear title and description
- Reference related issues (e.g., "Closes #42")
- Describe what changed and why
- Include screenshots for UI changes
- Ensure all tests pass
- Request review from maintainers
- Respond to comments
- Make requested changes
- Push updates to your branch
- Be patient and professional
jcurses uses automatic continuous versioning:
- Every push to
mainautomatically increments the minor version (X.Y format) - Version bumps are automated via CI/CD (no manual intervention)
- Current version is displayed in README.md badge and pom.xml
- This enables rapid iteration and clear tracking of changes
- Don't manually edit version numbers in pom.xml - they're auto-updated
- Each merged PR will trigger a new version release
- Version numbers reflect iteration count, not semantic versioning
- Focus on quality code - versioning is handled automatically
This approach prioritizes:
- Fast iteration - No manual release process
- Continuous deployment - Every merge is a release
- Clear history - Each version maps to specific commits
- Automation - Reduce manual overhead
- Indentation: 4 spaces (no tabs)
- Line Length: Max 120 characters
- Braces: Always use braces, even for single-line blocks
- Naming:
- Classes:
PascalCase - Methods/Variables:
camelCase - Constants:
UPPER_SNAKE_CASE - Packages:
lowercase
- Classes:
public class JButton extends Component {
private String label;
private final List<ActionListener> listeners = new ArrayList<>();
public void setLabel(String label) {
renderLock.lock();
try {
this.label = label;
} finally {
renderLock.unlock();
}
repaint();
}
@Override
public void paint(char[][] buffer) {
renderLock.lock();
try {
// Rendering logic
} finally {
renderLock.unlock();
}
}
}- Thread Safety: Use
renderLockfor all state modifications - Resource Management: Use try-finally for locks
- Null Checks: Validate parameters with
IllegalArgumentException - Immutability: Use
finalfor fields that don't change - Comments: Only add comments for non-obvious "why", not "what"
- Magic Numbers: Extract to named constants
Every contribution should include tests:
- New Features: Add comprehensive test coverage
- Bug Fixes: Add test that reproduces the bug
- Refactoring: Ensure existing tests pass
@DisplayName("JButton Tests")
class JButtonTest extends ComponentTestBase {
private JButton button;
@BeforeEach
void setUp() {
button = new JButton("Click Me");
button.setSize(20, 3);
button.setLocation(0, 0);
}
@Test
@DisplayName("should render label centered")
void testRendering() {
button.paint(buffer);
BufferAssertions.assertBufferContains(buffer, 0, 1, "Click Me");
}
@Test
@DisplayName("should be thread-safe")
void testThreadSafety() throws InterruptedException {
ThreadSafetyTestHelper.runConcurrent(10, () -> {
button.setLabel("Test");
});
}
}- Core Components: 85%+ coverage
- Event System: 90%+ coverage
- Overall: 80%+ coverage
- New Features: Update README, add to feature list
- API Changes: Update JavaDoc
- Breaking Changes: Update CHANGELOG and migration guide
- Examples: Add to InteractiveDemo if appropriate
README.md- Project overview and quick startQUICKSTART.txt- Detailed usage guideTESTING.md- Test documentation and guideINTERACTIVE_DEMO.md- Interactive demo documentation- JavaDoc comments for public API
If you have questions:
- Check existing documentation
- Search closed issues
- Open a new issue with the
questionlabel - Tag maintainers in your PR for guidance
By contributing, you agree that your contributions will be licensed under the GPL-3.0 License.
Happy Contributing! 🚀