Thank you for your interest in contributing! This guide explains how to set up your environment, run quality checks, and submit changes that meet the project's standards.
| Tool | Minimum Version |
|---|---|
| Flutter SDK | ≥ 3.10.0 |
| Dart SDK | ≥ 3.0.0 |
Run flutter pub get (or dart pub get) in the package root to fetch
dependencies.
Before opening a pull request, run the following checks locally — they are the same checks the CI pipeline executes:
# 1. Install / update dependencies
flutter pub get
# 2. Run the full test suite
flutter test
# 3. Verify formatting
dart format --set-exit-if-changed .
# 4. Run static analysis (path-dependency warnings are expected for local dev)
flutter analyzeAll four must pass before a PR will be reviewed.
lib/
├── davianspace_hosting_flutter.dart # Barrel export — public API surface
└── src/
├── service_provider_scope.dart # InheritedWidget (ServiceProvider → tree)
├── context_extensions.dart # BuildContext extension methods
├── flutter_host_runner.dart # Host.runFlutterApp / runFlutterAppAsync
└── host_provider.dart # Declarative StatefulWidget lifecycle
- One primary public type per file. Internal helpers (
_HostLifecycleObserver,_AsyncHostStartup) live in the same file as their public entry point. - The barrel file re-exports every
src/file — consumers should never import fromsrc/directly.
| Construct | Convention | Example |
|---|---|---|
| Public widget | UpperCamelCase |
HostProvider |
| Extension | UpperCamelCase |
ServiceResolution |
| Private helper | _UpperCamelCase |
_HostLifecycleObserver |
| Parameters | lowerCamelCase |
hostFactory, loadingBuilder |
| Test descriptions | lowercase sentence | 'resolves required service' |
- Use
final classfor concrete types that must not be extended. - Use
abstract interface classfor pure-interface contracts. - Prefer
Objectoverdynamicas the top type. - All public APIs must have
///doc comments including:- A one-line summary.
Throws/Returnssections where applicable.See alsocross-references.
- Use
constconstructors wherever possible. - Prefer
finalfields and local variables. - Guard
setStatecalls withmountedwhen preceded by anawait. - Keep
dispose()synchronous — use fire-and-forget for async teardown.
InheritedWidget.updateShouldNotifyshould use identity comparison (!=) rather than deep equality to avoid unnecessary rebuilds.- Lifecycle callbacks (
initState,dispose,didChangeAppLifecycleState) must be idempotent and safe to call multiple times. - Prefer
WidgetsBindingObserverover raw platform channels for app lifecycle events.
The test suite lives in test/. Tests use flutter_test with real DI
containers — no mocking framework is required.
# Run all tests
flutter test
# Run a single test file
flutter test test/davianspace_hosting_flutter_test.dart
# Run with coverage
flutter test --coverage- Create a
ServiceCollection, register test instances. - Build a
ServiceProvider. - Wrap the widget under test in
ServiceProviderScope. - Pump and assert.
final services = ServiceCollection()
..addInstance<MyService>(FakeMyService());
final provider = services.buildServiceProvider();
await tester.pumpWidget(
ServiceProviderScope(
provider: provider,
child: const WidgetUnderTest(),
),
);All new features or bug fixes must include corresponding tests.
Use Conventional Commits:
| Prefix | Purpose |
|---|---|
feat: |
New feature |
fix: |
Bug fix |
docs: |
Documentation only |
test: |
Adding or updating tests |
refactor: |
Code change that neither fixes nor adds |
chore: |
Maintenance (deps, CI, tooling) |
Example: feat: add getKeyedService extension method
- Create a feature branch from
master. - Make focused, atomic commits.
- Add or update tests for any changed behaviour.
- Ensure all four development checks pass (see above).
- Open a PR with a clear description of the change and the motivation.
- Address review feedback — the maintainer may request changes before merge.
Reviewers will verify:
- All four checks pass (
pub get,test,format,analyze). - Public API has complete
///documentation. - No new
dynamicusage without justification. - Lifecycle safety (
mountedguards, idempotent teardown). - Backward compatibility — no breaking changes without a major version bump.
- Test coverage for new or changed behaviour.
- Use the GitHub issue tracker for bugs and feature requests.
- For security vulnerabilities, see SECURITY.md.
For questions about contributing: developers@davian.space
By contributing, you agree that your contributions will be licensed under the MIT License.