Original address: medium.com/flutter-com…

Original article by Sagarsuri56.medium.com/

Published: June 5, 2021-7 minutes reading

Most of the time, when you create a Flutter project. You work with a single package. The project consists of a pubspec.yaml, lib folder. You put all your features and utilities in one package. But there are also projects that divide their functionality and utilities into multiple packages. This helps create a better separation of concerns and allows teams to open source some of their packages. Below is a schematic of a multi-package project.

Here, we divide the project into three levels. The first layer is the root project, which will hold a common configuration that applies to all the different packages in the project. The second layer consists of packages with independent functionality that do not depend on each other. The third layer consists of utility packages for multiple functional packages. I won’t go into the depth of how to create or construct a multi-package Flutter project. This article will focus on addressing a particular challenge that is often faced in multi-pack Flutter projects.

challenge

In a single package Flutter project, it is very simple to run the following tasks.

  1. flutter pub get
  2. flutter tset
  3. flutter analyze
  4. Generate code coverage, known as Flutter Test –coverage

But running the same tasks in a multi-package Flutter project can be challenging, because you need to run the tasks in each package in the project and give a summary result when the tasks are completed. Now we know what the challenge is. Let’s discuss some of the possible solutions.

The solution

There are two possible solutions to this challenge. Let’s look at the first one.

  1. Write bash scripts for various tasks.

It’s definitely a solution, but it’s not a smart one. You need to write a script that finds all the packages in your project and runs one of the above tasks in them. You also need to make sure that you display the output in a nice format to make things readable. If you prefer a GUI, then you need to create some configuration in your IDE to run your scripts through the GUI. 2. Integrate Melos into your project. This is a smarter plan than the first one, and I highly recommend it. So let’s talk in detail about what Melos is and how to integrate it into your multi-package project.

The introduction of Melos

Melos is a CLI tool for managing multi-package Flutter/Dart projects.

Melos was developed by a well-known team in the Flutter community, Invertase. You can learn more about Melos on their website, but here’s a quick list of what Melos has to offer.

  • Automatically generates version and update logs.
  • Automatically publish software packages to pub.dev.
  • Link and install the local software package.
  • Run the commands of each software package simultaneously.
  • Lists local packages and their dependencies.

Now let’s see how to perform all of the above tasks using Melos.

Note: If you want to learn by doing, download the startup project. In another branch, you can find the final version of the project.

Installation of Melos

Let’s install Melos first. I’m assuming you’ve installed the Flutter SDK and set the path of the Flutter and Dart to BASH_profile. Run the following command on your terminal.

dart pub global activate melos
Copy the code

You can copy this command from the image above

The next step is to open your startup project in your IDE. I prefer using Intellij and will show you some of the great GUI features that Melos has to offer. The structure of the project should look like this.

Now create a file called melos.yamlin and use it as your root application. And copy the following into it.

name: melos_demo

packages:
  - utility/**
  - features/**
  - The '*'
Copy the code

You can copy the code from the image above

Let’s understand the script above. A) name: You must give the name of your project. You can find it in the root project’s pubspec.yaml. B) Pacakge: This list should contain the path of each package in your project. Each path can be defined using the GLOb pattern extension format.

Melos Bootstrap

Now run the following command from your root project on the terminal to connect all your local packages together and update the dependencies, that is, flutter pub get.

melos bootstrap
Copy the code

Be sure to run this command from within the root project

After running the above command, you should see the following output.

You can read why you need to guide Melos here. Specifically, it is one of the most important commands you should execute when setting Melos in a project or when cleaning up in a project.

Melos Clean

You can execute this command when you want to delete temporary files (build artifacts, pub files, etc.) from your project. The command looks like this.

melos clean
Copy the code

You can copy this command from the picture above

The command

Now you will create different commands to implement the tasks we mentioned at the beginning of this article.

A. Running test cases in a specific package:

Write the following command in your melos.yaml file.

name: melos_demo

packages:
  - utility/**
  - features/**
  - The '*'
  
scripts:
  test:selective_unit_test:
    run: melos exec --dir-exists="test" --fail-fast -- flutter test --no-pub --coverage
    description: Run Flutter tests for a specific package in this project.
    select-package:
      flutter: true
      dir-exists: test
Copy the code

The colors in the picture above look strange. Blame it on carbon.now.sh 😅

Let’s take a look at what happens in the above script.

  1. You have created a custom script, i.etest:selective_unit_testOnce executed, an option is displayed to select the package of unit tests you want to run.
  2. Melos provides powerful filtering options to select packages that match the filtering criteria. In the above script, you use--dir-exists="test"As a filter option. This filters out all packages that contain TestFolder. You can find more filtering options on their website.
  3. --fail-fastExecution of the script is terminated immediately upon a failed test case.
  4. You can give each script a human-readable one by using the description sectiondescribe.
  5. You must be wondering why this command is namedtest:selective_unit_test. The next command will answer your question. 😃
  6. You can read more about what Melos Exec does. Basically, it will execute commands or scripts in every package in your project.

Now run the following command.

melos run test:selective_unit_test
Copy the code

You can copy this command from the image above

You will see the output below.

The above command finds the packages that contain the test folder. Enter 2 as an option and you will see the following output.

B. Run the test cases in all packages:

Now write the following command, which will run all the unit test cases in your project. This will not prompt for any option selection.

scripts:
  test:
    run: melos run test:selective_unit_test --no-select
    description: Run all Flutter tests in this project.
Copy the code

Let’s discuss what these commands do.

  1. This command basically runs the previous command with –no-select as the argument. This means running all the unit tests.
  2. You can use melos run test to run this command. You named this command test because you can have multiple variations of the test command, like the test you created in the previous step :selective_unit_test. You can also create more variants, such as test:e2e_test, test:bdd_test, etc. You can combine all the variants and run them in a single command, test.

C. Run analysis of all packages:

Create the following commands in the script section.

analyze:
    run: melos exec -- flutter analyze .
    description: Run `dart analyze` in all packages.
Copy the code

You can copy this script from the image above

There’s nothing fancy here. You can run the analyze function in all software packages by executing melos Run Analyze.

D. Generate code coverage for the entire project:

To generate code coverage for the entire project. A custom script is included in the project, combine_coverage.sh. This basically merges all the lcov.info files from different packages into a single lcov.info file. You can then use this method to convert the lcov.info file to HTML.

#! /usr/bin/env bash

escapedPath="$(echo `pwd` | sed 's/\//\\\//g')"

if grep flutter pubspec.yaml > /dev/null; then
  if [ -d "coverage" ]; then
    # combine line coverage info from package tests to a common file
    if [ ! -d "$MELOS_ROOT_PATH/coverage_report" ]; then
      mkdir "$MELOS_ROOT_PATH/coverage_report"
    fi
    sed "s/^SF:lib/SF:$escapedPath\/lib/g" coverage/lcov.info >> "$MELOS_ROOT_PATH/coverage_report/lcov.info"
    rm -rf "coverage"
  fi
fi
Copy the code

You can copy this script from the image above

Write the following commands in the script section.

gen_coverage: melos exec -- "\$MELOS_ROOT_PATH/combine_coverage.sh"
Copy the code

You can copy the script from the image above

MELOS_ROOT_PATH will give you a path to melos.yaml, the root project. After the script is executed. You can see the coverage_Report folder in the project. Now you have an lcov.info file that will provide you with a report on the entire project. In the end, your melos.yaml file will look like this.

name: melos_demo

packages:
  - utility/**
  - features/**
  - The '*'
scripts:
  test:selective_unit_test:
    run: melos exec --dir-exists="test" --fail-fast -- flutter test --no-pub --coverage
    description: Run Flutter tests for a specific package in this project.
    select-package:
      flutter: true
      dir-exists: test

  test:
    run: melos run test:selective_unit_test --no-select
    description: Run all Flutter tests in this project.

  analyze:
    run: melos exec -- flutter analyze .
    description: Run `dart analyze` in all packages.

  gen_coverage: melos exec -- "\$MELOS_ROOT_PATH/combine_coverage.sh"
Copy the code

You can copy the script in the picture

GUI options

If you want to run these commands using a GUI rather than a terminal, Melos is there for you. After all the commands have been added, you can run the bootstrap command again. This will produce some configuration, and you can see some GUI options like this.

Now you can execute all these commands without typing anything in the terminal. 😄

Next steps

This is just the tip of the iceberg. You can learn more about filtering options and commands on the Melos website. Hope you enjoyed this article. Please connect with me on Twitter and LinkedIn. Stay safe, stay healthy. 😃


www.deepl.com translation