Components
Components allow you to isolate and categorize coverage data from your project with virtual filters.
Components allow you to isolate and categorize coverage data from your project with virtual filters. It is similar to Flags, but there is no direct relationship between Components and the reports you upload. The most important differentiator between Components and Flags is that Components do not have to be supplied at upload time, they are fully defined in the codecov.yml
.
Components are particularly useful to create custom statuses and get coverage information from parts of your code that are not easily broken up into different uploads, or span multiple flag groups.
Currently you can get component information in the PR comment and also have component-based statuses. See examples below. The yaml configuration that generated the example statuses are discussed later in this guide.
Components Usage
To use components you just need to define your filters and optional statuses in your codecov.yaml
.
To have a more concrete example, and better understand the differences of components and flags, let's consider an example with the following repo structure (you can check out the example repo in github)
|-- core/
| |
| |-- tests/
| |-- __init__.py
| |-- main.py
|
|-- emotions/
| |
| |-- tests/
| |-- __init__.py
| |-- ascii.py
| |-- emoji.py
|
|-- fruits/
|
|-- tests/
|-- __init__.py
|-- ascii.py
|-- emoji.py
Let's assume we only have 1 flag - unit
- that makes a single upload with all the coverage information that we have from all the tests in the repo.
Given that fact, we can't have statuses based on the emotions
or the fruits
modules. To make that using flags we would have to break up out uploads into 3 separate flags, namely unit
(to keep the data we had before), emotions
, and fruits
. That would also require that we upload the coverage info for each flag separately, for a total of 3 uploads. Depending on the structure of the project and its tests, supplying these coverage reports separately may be very difficult to do.
We can achieve the same effect using components by defining path filters we're interested in in our codecov.yaml
.
Actually we can go a step further and filter paths that are not under a folder (and therefore would not be able to be defined using just flags), but can be related somehow. For example in the definition below we have ascii
and emoji
components that group all ascii.py
and emoji.py
files respectively.
# ... previous config options...
component_management:
default_rules: # default rules that will be inherited by all components
statuses:
- type: project # in this case every component that doens't have a status defined will have a project type one
target: auto
branches:
- "!main"
individual_components:
- component_id: module_emotions # this is an identifier that should not be changed
name: emotions # this is a display name, and can be changed freely
paths:
- emotions/**
- component_id: module_fruits
name: fruits
paths:
- fruits/**
- component_id: module_core
name: core
paths:
- core/**
statuses: # the core component has its own statuses
- type: project
target: auto
- type: patch
- component_id: ascii
paths:
- .*/ascii.py
- component_id: emoji
paths:
- .*/emoji.py
comment:
layout: "header, diff, flags, components" # show component info in the PR comment
behavior: default
require_changes: no
require_base: no
Component Options
Below are the configuration options commented for components. Very similar to flag management configuration.
component_management:
default_rules: # Dict. rules inherited by all components that don't define a tag for themselves.
paths: # List. Path filters.
- "specific_file.txt
- "^some.*regex$"
- "glob/*"
flag_regexes: # List. Flags to be included in the component.
- "fruit.*"
statuses: # List. Status definitions.
# These statuses are the same as for flag_management
# Except they don't accept 'flags'
individual_components: # List. These are the actual components.
- component_id: component_1 # String. Required.
name: display_name_1 # String. Optional.
# Individual components also accept paths, flag_regexes and statuses
- component_id: other_component
#...
Should I use Flags or Components?
If you have a new project, the correct answer is likely Components. If you already have a robust Flags-based setup in your project and it is working for you/your team, you should likely stick with Flags.
As of this writing, Flags do have more support in the Codecov UI than Components, but that is expected to change in the future as we build more Component support into the Codecov UI. However, if you require per-flag coverage trend information and UI support immediately, then it is recommend to use Flags for the time being.
Flags and Paths Rules
If both flag_regexes and paths are defined for a component, that filter is AND-style. That means that for a file to be considered part of the component it needs to have coverage from one of the flags AND be in one of the paths defined.
Updated about 2 years ago