Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .fvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"flutter": "3.41.3"
}
111 changes: 57 additions & 54 deletions .github/workflows/sonar-qube-scann.yml
Original file line number Diff line number Diff line change
@@ -1,64 +1,67 @@
# name: sonarqube
name: sonarqube

# # ────────────────────────────────────────────────────────────────
# # CI TRIGGERS
# # · push on main → historical baseline
# # · pull_request PRs → quality gate before merge
# # ────────────────────────────────────────────────────────────────
# on:
# push:
# branches: [main]
# pull_request:
# types: [opened, synchronize, reopened]
# ────────────────────────────────────────────────────────────────
# CI TRIGGERS
# · push on main → historical baseline
# · pull_request PRs → quality gate before merge
# ────────────────────────────────────────────────────────────────
on:
push:
branches: [main]
pull_request:
types: [opened, synchronize, reopened]

# jobs:
# sonarQubeTrigger:
# name: Sonarqube Trigger
# runs-on: ubuntu-latest
jobs:
sonarQubeTrigger:
name: Sonarqube Trigger
runs-on: ubuntu-latest

# steps:
# # 1 — Checkout the repo
# - name: Checkout code
# uses: actions/checkout@v3
steps:
# 1Checkout the repo
- name: Checkout code
uses: actions/checkout@v4

# # 2 — SSH agent for any Git-based pub dependencies
# - name: Start ssh-agent
# uses: webfactory/ssh-agent@v0.9.0
# with:
# ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
# 2SSH agent for any Git-based pub dependencies
- name: Start ssh-agent
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

# # 3 — Install Dart SDK
# - uses: dart-lang/setup-dart@v1
# 3 — Read the pinned Flutter version from .fvmrc
- name: Read Flutter version
id: fvm
run: echo "version=$(jq -r '.flutter' .fvmrc)" >> "$GITHUB_OUTPUT"

# # 4 — Install Flutter SDK
# - name: Set up Flutter
# uses: subosito/flutter-action@v2
# with:
# channel: stable
# flutter-version: 3.24.3
# 4Install Flutter SDK at the pinned version
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
flutter-version: ${{ steps.fvm.outputs.version }}

# # 5 — Install all pub packages (app + each module)
# - name: Get pub packages
# run: |
# set -e
# for dir in app modules/*; do
# if [ -f "$dir/pubspec.yaml" ]; then
# echo "▶ flutter pub get --directory $dir"
# flutter pub get --directory "$dir"
# fi
# done
# 5 — Install Melos
- name: Install Melos
run: dart pub global activate melos

# # 6 — Static analysis (kept exactly as before)
# - name: Analyze App
# run: flutter analyze
# 6 — Resolve workspace dependencies
- name: Bootstrap workspace
run: melos bootstrap

# # 7 — Install SonarScanner CLI (needed by full_coverage.py)
# - name: Setup Sonarqube Scanner
# uses: warchant/setup-sonar-scanner@v8
# 7 — Static analysis
- name: Analyze
run: melos run analyze

# # 8 — Run tests, build combined lcov.info and upload to SonarQube
# - name: Generate coverage & run SonarQube
# run: python3 coverage/full_coverage.py --ci
# env:
# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
# SONAR_URL: ${{ secrets.SONAR_URL }}
# 8 — Run tests (each package)
- name: Run tests
run: melos exec --dir-exists=test -- flutter test

# 9 — Install SonarScanner CLI (needed by full_coverage.py)
- name: Setup Sonarqube Scanner
uses: warchant/setup-sonar-scanner@v8

# 10 — Generate coverage & run SonarQube
- name: Generate coverage & run SonarQube
run: python3 coverage/full_coverage.py --ci
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_URL: ${{ secrets.SONAR_URL }}
10 changes: 7 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
.classpath
.project
.settings/
.vscode/
.vscode/*
!.vscode/settings.json

# FVM (Flutter Version Management)
.fvm/

# Flutter repo-specific
/bin/cache/
Expand Down Expand Up @@ -110,7 +114,7 @@ unlinked_spec.ds

# Coverage
coverage/
+!coverage/full_coverage.py
!coverage/full_coverage.py

# Symbols
app.*.symbols
Expand All @@ -129,4 +133,4 @@ app.*.symbols
/modules/data/.flutter-plugins-dependencies
/modules/domain/.flutter-plugins
/modules/domain/.flutter-plugins-dependencies
/.idea/
/.idea/
9 changes: 9 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"dart.flutterSdkPath": ".fvm/flutter_sdk",
"search.exclude": {
"**/.fvm": true
},
"files.watcherExclude": {
"**/.fvm": true
}
}
47 changes: 39 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,45 @@ This template comes with:

![template](app/template.png)
2. Clone your new repo.
3. Install [Melos](https://melos.invertase.dev/getting-started) globally executing: `dart pub global activate melos`.
4. test: `melos -v` * note: if your terminal don't recognize melos command, you can add the following line to your .zshrc or .bashrc file:*
3. Install [FVM](https://fvm.app) (Flutter Version Management):
```text
dart pub global activate fvm
```
4. Install the Flutter SDK version pinned in `.fvmrc`:
```text
fvm install
```
This downloads the exact Flutter version the repo is pinned to and links it at `.fvm/flutter_sdk`. All contributors and CI use the same version.
5. Run Flutter commands through FVM:
```text
fvm flutter <command>
```
Optionally add a shell alias (`alias flutter='fvm flutter'`) so you can keep typing `flutter ...`.
6. Install [Melos](https://melos.invertase.dev/getting-started) 7.x globally:
```text
dart pub global activate melos
```
7. Verify melos is on the path: `melos --version`. If your shell does not find the command, add `pub-cache` to `PATH` (e.g. in `~/.zshrc` or `~/.bashrc`):
```text
export PATH="$PATH":"$HOME/.pub-cache/bin"
```
5. Run `melos doctor`.
6. Run `melos pub:get`.
7. Setup Android:
```
8. Bootstrap the workspace (downloads packages for every workspace member):
```text
melos bootstrap
```
9. Run `melos doctor` to verify the setup.

> Melos 7 uses [Dart pub workspaces](https://dart.dev/tools/pub/workspaces). The workspace is declared in the root `pubspec.yaml`, each package sets `resolution: workspace`, and there is a single shared `pubspec.lock` at the repo root.

### Upgrading the pinned Flutter version

When the team agrees to move to a new Flutter version, run `fvm use <version>` at the repo root and commit the updated `.fvmrc`. CI reads the pinned version from `.fvmrc`, so the change propagates automatically.

### IDE setup

- **VS Code**: settings are already wired in `.vscode/settings.json` — the Dart extension picks up `.fvm/flutter_sdk` automatically.
- **Android Studio / IntelliJ**: open `Preferences → Languages & Frameworks → Flutter` and set the SDK path to `<repo>/.fvm/flutter_sdk`.
10. Setup Android:
- Add to the build.properties file (and update when needed):
```text
flutter.versionName=1.0.0
Expand All @@ -46,7 +77,7 @@ This template comes with:
flutter.targetSdkVersion=33
```

8. Android SignIn
11. Android SignIn
- Create your release Key Store:

```text
Expand All @@ -62,7 +93,7 @@ This template comes with:
storeFile=<FilePath>
```

9. Add your env vars, create a config file for each env:
12. Add your env vars, create a config file for each env:
![me](env_config_files.png)
- add the env config, i.e:

Expand Down
91 changes: 2 additions & 89 deletions app/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,98 +1,11 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
# Lint rules come from `package:flutter_lints/flutter.yaml`. To customize, add
# entries under `linter.rules` below.
include: package:flutter_lints/flutter.yaml

linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
analyzer:
plugins:
- dart_code_metrics
dart_code_metrics:
anti-patterns:
- long-parameter-list
metrics:
cyclomatic-complexity: 20
maximum-nesting-level: 5
number-of-parameters: 4
source-lines-of-code: 15
metrics-exclude:
- test/**
rules:
- avoid-nested-conditional-expressions:
acceptable-level: 2
- prefer-correct-identifier-length:
max-identifier-length: 30
min-identifier-length: 2
- no-equal-arguments:
ignored-parameters:
- height
- width
- backspaceColor
- skinToneIndicatorColor
- enabled
- fontFamily
- color
- focusedBorder
- enabledBorder
- subtitle2
- subtitle1
- overline
- headline4
- bodyText1
- bodyText2
- button
- caption
- headline1
- headline2
- headline3
- headline5
- headline6
- verticalPadding
- horizontalPadding
- topRightRadius
- topLeftRadius
- bottomRightRadius
- bottomLeftRadius
- topLeft
- bottomLeft
- contentBorderColor
- no-boolean-literal-compare
- no-empty-block
- no-equal-then-else
- avoid-missing-enum-constant-in-map
- avoid-non-null-assertion
- avoid-unnecessary-type-assertions
- avoid-unnecessary-type-casts
- double-literal-format
- no-equal-then-else
- no-magic-number
- no-object-declaration
- prefer-async-await
- prefer-first
- prefer-immediate-return
- prefer-last
- prefer-match-file-name
- prefer-trailing-comma
- avoid-border-all
- avoid-wrapping-in-padding
- prefer-const-border-radius
1 change: 0 additions & 1 deletion app/lib/main/init.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';


void init() async {
WidgetsFlutterBinding.ensureInitialized();
usePathUrlStrategy();
Expand Down
4 changes: 3 additions & 1 deletion app/lib/presentation/resources/custom_network_image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ class CustomNetworkImage extends StatelessWidget {
imageUrl ?? "",
width: width,
height: height,
colorFilter: color != null ? ColorFilter.mode(svgIconColor!, BlendMode.srcIn) : null,
colorFilter: color != null
? ColorFilter.mode(svgIconColor!, BlendMode.srcIn)
: null,
),
)
: Container(
Expand Down
3 changes: 2 additions & 1 deletion app/lib/presentation/resources/images.dart
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ class _SvgImage {
width: width,
height: height,
fit: fit,
colorFilter: color != null ? ColorFilter.mode(color, BlendMode.srcIn) : null,
colorFilter:
color != null ? ColorFilter.mode(color, BlendMode.srcIn) : null,
alignment: alignment,
semanticsLabel: semanticLabel,
package: package,
Expand Down
Loading