Skip to content

chore(lint): migrate linting and formatting to ruff - #2436

Open
sbrunato wants to merge 5 commits into
developfrom
ruff
Open

sbrunato wants to merge 5 commits into
developfrom
ruff

Conversation

@sbrunato

@sbrunato sbrunato commented Nov 5, 2026

Copy link
Copy Markdown
Collaborator

Replace the legacy lint and formatting tools with ruff, configure its rules and hooks, update CI and contributor guidance, and format the codebase.

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Benchmark comparison

Compared baseline: origin/develop
Compared candidate: c0aa04b


------------------------------- benchmark: 9 tests, 2 sources -------------------------------
Name (time in us)                                 baseline Median  candidate Median   ΔMedian
---------------------------------------------------------------------------------------------
test_benchmark_eoproduct_assets_population                12.2350           12.3140     +0.6%
test_benchmark_eoproduct_instantiation                    26.5950           27.2070     +2.3%
test_benchmark_stac_reader_fetch_recursive             3,872.0830        3,796.9680     -1.9%
test_benchmark_cli_version                            14,863.1150       14,650.2850     -1.4%
test_benchmark_cli_without_args_subprocess           131,666.2345      131,593.3135     -0.1%
test_benchmark_core_search_with_provider             133,911.7330      132,897.0560     -0.8%
test_benchmark_core_search_with_count                173,488.0475      169,792.9110     -2.1%
test_benchmark_cli_list_collections                  279,178.8690      274,756.8990     -1.6%
test_benchmark_eodag_instantiation_subprocess        960,811.8980      949,403.2755     -1.2%
---------------------------------------------------------------------------------------------

Legend:
  Cyan: reference source for comparison. Green: improvement, Red: regression.
  Δ: percentage change from reference source.

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Test Results

    5 files  ±0      5 suites  ±0   2m 43s ⏱️ -5s
1 052 tests ±0  1 052 ✅ ±0  0 💤 ±0  0 ❌ ±0 
5 905 runs  ±0  5 903 ✅ ±0  2 💤 ±0  0 ❌ ±0 

Results for commit a1f5588. ± Comparison against base commit 8420c52.

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

badge

Code Coverage (Ubuntu)

Details
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                     18       2  88.89%   60, 69
cli.py                                         293      11  96.25%   110-121, 386, 727
config.py                                      420      38  90.95%   224, 247-261, 283, 288, 322-324, 327, 330, 333, 337, 341, 345-347, 843-845, 896, 1031-1033, 1057-1061, 1080, 1088, 1116-1121, 1123
crunch.py                                        2       0  100.00%
api/__init__.py                                  0       0  100.00%
api/collection.py                              153       7  95.42%   199, 235, 345, 384, 387, 405, 408
api/core.py                                    755      26  96.56%   156, 270, 282-293, 533, 581, 618, 658, 676, 747, 844-848, 870, 1023, 1028, 1290, 1361, 1660, 1886, 2043, 2047, 2156
api/provider.py                                414      44  89.37%   140-144, 210, 214-215, 352-373, 441, 557, 561-562, 567-570, 581, 642-643, 699-709, 909-910, 968, 975, 989, 1012-1015, 1049-1056, 1060-1061
api/search_result.py                           137      12  91.24%   110, 122, 132, 153, 207, 265, 277, 410, 465-468
api/product/__init__.py                         26       4  84.62%   51-54
api/product/_assets.py                          78       5  93.59%   141, 249-250, 262-266
api/product/_product.py                        348      26  92.53%   219, 376, 402-405, 442, 461-462, 553, 581, 588, 627, 676, 682, 819, 862-865, 874-877, 930, 1020, 1032, 1100
api/product/metadata_mapping.py                921      60  93.49%   116, 185-187, 302-307, 331, 389-390, 470, 490-491, 496, 559-560, 597, 618-621, 644, 656-657, 699, 722, 747-750, 752-757, 814, 850, 856, 872, 880, 1111, 1263-1264, 1293, 1302-1306, 1323-1328, 1461, 1484, 1493, 1515, 1520, 1590, 1687, 1708, 1734, 1748, 1846, 1943, 2047, 2113, 2156
api/product/drivers/__init__.py                 11       0  100.00%
api/product/drivers/base.py                     32       0  100.00%
api/product/drivers/generic.py                  11       0  100.00%
api/product/drivers/sentinel1.py                33       0  100.00%
api/product/drivers/sentinel2.py                33       0  100.00%
plugins/__init__.py                              0       0  100.00%
plugins/base.py                                 39       3  92.31%   49, 82-83
plugins/manager.py                             211      12  94.31%   101-106, 136, 260, 264, 291, 345, 449-452
plugins/apis/__init__.py                         0       0  100.00%
plugins/apis/base.py                             8       0  100.00%
plugins/apis/ecmwf.py                           99      11  88.89%   110, 168-170, 218-219, 245-247, 278-279
plugins/apis/usgs.py                           177      26  85.31%   146, 161, 249, 282, 325-327, 332, 360-361, 366, 396-403, 414-419, 441-447
plugins/authentication/__init__.py               6       1  83.33%   32
plugins/authentication/aws_auth.py             127      28  77.95%   69-70, 142-149, 193-212, 234, 266-270, 287, 311, 327-328
plugins/authentication/base.py                  26       4  84.62%   61, 74, 97, 111
plugins/authentication/eoiam.py                102       1  99.02%   170
plugins/authentication/generic.py               16       3  81.25%   50, 55, 65
plugins/authentication/header.py                19       0  100.00%
plugins/authentication/keycloak.py              46       4  91.30%   154, 177-182
plugins/authentication/openid_connect.py       243      21  91.36%   101-102, 109-127, 174, 182, 196, 216, 362-365, 391, 432, 620-623
plugins/authentication/qsauth.py                34       1  97.06%   91
plugins/authentication/sas_auth.py             134       4  97.01%   135, 141, 177, 224
plugins/authentication/token.py                141       9  93.62%   192, 229, 309-310, 358-362
plugins/authentication/token_exchange.py        36       3  91.67%   75, 114-115
plugins/crunch/__init__.py                       6       0  100.00%
plugins/crunch/base.py                          12       0  100.00%
plugins/crunch/filter_date.py                   47       0  100.00%
plugins/crunch/filter_latest_intersect.py       52       6  88.46%   87-88, 95-96, 98-102
plugins/crunch/filter_latest_tpl_name.py        35       0  100.00%
plugins/crunch/filter_overlap.py                66      10  84.85%   118-121, 137-161
plugins/crunch/filter_property.py               30       2  93.33%   81-84
plugins/download/__init__.py                     4       0  100.00%
plugins/download/aws.py                        426      43  89.91%   275, 309, 377-380, 412-413, 421-425, 534-537, 577-579, 583, 613-614, 620-624, 654, 721-733, 819, 836, 851, 883-884, 947, 973, 1018-1020, 1072
plugins/download/base.py                       300      25  91.67%   148, 178, 400-401, 445, 463, 479, 556-560, 590, 625-626, 650-659, 718, 739, 761, 769
plugins/download/http.py                       584      72  87.67%   257, 272, 364-367, 370, 377-382, 414-415, 432, 447, 508, 541, 554, 568, 581-585, 601-606, 617, 636, 672-675, 696, 706, 713, 755, 877, 911, 943-952, 988, 1033-1038, 1047, 1062-1064, 1068, 1071, 1099, 1119, 1177, 1229, 1272-1273, 1285, 1295, 1351-1352, 1382, 1409, 1428, 1508-1509
plugins/search/__init__.py                      25       0  100.00%
plugins/search/base.py                         220      20  90.91%   119, 123, 147-153, 162, 228-231, 264, 314, 346, 367, 500, 585-588, 597
plugins/search/build_search_result.py          565      45  92.04%   258, 354, 435-441, 521-522, 571, 582-584, 608, 610, 675, 683-687, 707, 717, 743, 792, 817, 879-884, 943, 970, 973, 1081, 1216, 1231, 1234, 1259, 1381, 1396, 1437-1438, 1482, 1491-1493, 1548, 1594
plugins/search/cop_ghsl.py                     408      28  93.14%   72-73, 108-109, 173, 175, 217, 297, 313, 359, 383, 403, 424, 458, 474, 509, 538-539, 552-554, 565-567, 592, 612, 649, 653
plugins/search/cop_marine.py                   301      34  88.70%   56, 64-66, 82, 104, 106, 109, 175-176, 196, 220, 226, 230, 252-253, 261, 308, 318, 331, 339, 345-349, 366, 398-401, 416, 486, 498, 541-542
plugins/search/creodias_s3.py                   29       1  96.55%   59
plugins/search/csw.py                          120      12  90.00%   124, 168, 206, 217-228, 233
plugins/search/eumetsat_ds.py                   24       0  100.00%
plugins/search/geodes.py                        66       0  100.00%
plugins/search/oar.py                           84      15  82.14%   50, 57-60, 171-182, 188-190, 197
plugins/search/qssearch.py                     923      85  90.79%   372, 534-535, 558-559, 571-575, 875, 914, 944, 978, 1013, 1063, 1083, 1086-1087, 1117-1118, 1136, 1207, 1216, 1228-1238, 1247, 1262, 1271, 1284, 1307, 1348, 1422, 1460, 1533-1534, 1536-1541, 1543-1544, 1615, 1822, 1825, 1829-1830, 1849-1852, 1866, 1893, 1911-1925, 1936, 1985-1991, 1998, 2082, 2087-2088, 2118, 2238, 2242, 2253, 2278, 2291, 2299-2309, 2335
plugins/search/stac_list_assets.py              25       0  100.00%
plugins/search/static_stac_search.py            86      18  79.07%   99-127, 164, 168-171, 184
resources/__init__.py                            0       0  100.00%
resources/shp/__init__.py                        0       0  100.00%
types/__init__.py                              228      55  75.88%   59, 74-76, 97-101, 114-144, 181-188, 203, 213, 308, 341, 351-369, 374, 376, 378, 400, 405, 413, 423
types/bbox.py                                   39       0  100.00%
types/download_args.py                           9       0  100.00%
types/queryables.py                            152       1  99.34%   395
types/search_args.py                            71      18  74.65%   67-71, 78-95, 110
types/stac_extensions.py                       162       4  97.53%   455-461, 641
types/stac_metadata.py                         161      22  86.34%   98, 120, 153, 186-188, 202-216, 225-232, 259-262
utils/__init__.py                              662      21  96.83%   57, 214, 221, 237, 272, 349, 601-604, 644-645, 674, 1058-1061, 1129-1130, 1162, 1370, 1482, 1614
utils/cache.py                                  23       0  100.00%
utils/dates.py                                 191       1  99.48%   182
utils/deserialize.py                            74      10  86.49%   53, 55, 103, 108-109, 148, 162, 184-185, 191
utils/env.py                                     3       0  100.00%
utils/exceptions.py                             58       0  100.00%
utils/free_text_search.py                       65       2  96.92%   83, 91
utils/import_system.py                          28       6  78.57%   65-73
utils/logging.py                                42       3  92.86%   42-43, 61
utils/notebook.py                               43      12  72.09%   40, 57-61, 71-77, 85-86
utils/repr.py                                   38       0  100.00%
utils/requests.py                               55       6  89.09%   94, 110, 118-120, 128
utils/s3.py                                    307      24  92.18%   97-99, 104, 110, 116, 120, 133, 137, 303-304, 345, 361, 383, 605, 688-689, 751, 793-797, 851
utils/stac_reader.py                           113      42  62.83%   63-85, 101, 138, 154-159, 206-216, 226-256
utils/streamresponse.py                         91       4  95.60%   105, 165, 174, 186
utils/yaml.py                                   42       7  83.33%   49, 65, 70-74
TOTAL                                        12244    1020  91.67%

Diff against develop

Filename                                 Stmts    Miss  Cover
-------------------------------------  -------  ------  -------
cli.py                                      +1       0  +0.02%
config.py                                   +1       0  +0.02%
api/collection.py                           -1       0  -0.03%
api/search_result.py                        -1       0  -0.06%
api/product/metadata_mapping.py             +2       0  +0.02%
plugins/base.py                             +1       0  +0.20%
plugins/apis/ecmwf.py                       +4      +1  -0.58%
plugins/apis/usgs.py                        +2      +1  -0.40%
plugins/download/http.py                    +2      +1  -0.13%
plugins/search/build_search_result.py       +9      +4  -0.59%
plugins/search/cop_ghsl.py                  -2      +1  -0.27%
plugins/search/cop_marine.py                +4       0  +0.15%
plugins/search/csw.py                       +2       0  +0.17%
plugins/search/oar.py                       +2      +2  -2.01%
plugins/search/qssearch.py                 +12      +4  -0.32%
plugins/search/static_stac_search.py        +2      +1  -0.69%
types/stac_metadata.py                      +2       0  +0.18%
utils/__init__.py                           +2       0  +0.01%
utils/notebook.py                           -1      -1  +1.64%
TOTAL                                      +43     +14  -0.08%

Results for commit: a1f5588

Minimum allowed coverage is 70%

♻️ This comment has been updated with latest results

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

badge

Code Coverage (Windows)

Details
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                     18       2  88.89%   60, 69
cli.py                                         293      11  96.25%   110-121, 386, 727
config.py                                      420      38  90.95%   224, 247-261, 283, 288, 322-324, 327, 330, 333, 337, 341, 345-347, 843-845, 896, 1031-1033, 1057-1061, 1080, 1088, 1116-1121, 1123
crunch.py                                        2       0  100.00%
api/__init__.py                                  0       0  100.00%
api/collection.py                              153       7  95.42%   199, 235, 345, 384, 387, 405, 408
api/core.py                                    755      26  96.56%   156, 270, 282-293, 533, 581, 618, 658, 676, 747, 844-848, 870, 1023, 1028, 1290, 1361, 1660, 1886, 2043, 2047, 2156
api/provider.py                                414      44  89.37%   140-144, 210, 214-215, 352-373, 441, 557, 561-562, 567-570, 581, 642-643, 699-709, 909-910, 968, 975, 989, 1012-1015, 1049-1056, 1060-1061
api/search_result.py                           137      12  91.24%   110, 122, 132, 153, 207, 265, 277, 410, 465-468
api/product/__init__.py                         26       4  84.62%   51-54
api/product/_assets.py                          78       5  93.59%   141, 249-250, 262-266
api/product/_product.py                        348      26  92.53%   219, 376, 402-405, 442, 461-462, 553, 581, 588, 627, 676, 682, 819, 862-865, 874-877, 930, 1020, 1032, 1100
api/product/metadata_mapping.py                921      60  93.49%   116, 185-187, 302-307, 331, 389-390, 470, 490-491, 496, 559-560, 597, 618-621, 644, 656-657, 699, 722, 747-750, 752-757, 814, 850, 856, 872, 880, 1111, 1263-1264, 1293, 1302-1306, 1323-1328, 1461, 1484, 1493, 1515, 1520, 1590, 1687, 1708, 1734, 1748, 1846, 1943, 2047, 2113, 2156
api/product/drivers/__init__.py                 11       0  100.00%
api/product/drivers/base.py                     32       0  100.00%
api/product/drivers/generic.py                  11       0  100.00%
api/product/drivers/sentinel1.py                33       0  100.00%
api/product/drivers/sentinel2.py                33       0  100.00%
plugins/__init__.py                              0       0  100.00%
plugins/base.py                                 39       3  92.31%   49, 82-83
plugins/manager.py                             211      12  94.31%   101-106, 136, 260, 264, 291, 345, 449-452
plugins/apis/__init__.py                         0       0  100.00%
plugins/apis/base.py                             8       0  100.00%
plugins/apis/ecmwf.py                           99      11  88.89%   110, 168-170, 218-219, 245-247, 278-279
plugins/apis/usgs.py                           177      26  85.31%   146, 161, 249, 282, 325-327, 332, 360-361, 366, 396-403, 414-419, 441-447
plugins/authentication/__init__.py               6       1  83.33%   32
plugins/authentication/aws_auth.py             127      28  77.95%   69-70, 142-149, 193-212, 234, 266-270, 287, 311, 327-328
plugins/authentication/base.py                  26       4  84.62%   61, 74, 97, 111
plugins/authentication/eoiam.py                102       1  99.02%   170
plugins/authentication/generic.py               16       3  81.25%   50, 55, 65
plugins/authentication/header.py                19       0  100.00%
plugins/authentication/keycloak.py              46       4  91.30%   154, 177-182
plugins/authentication/openid_connect.py       243      21  91.36%   101-102, 109-127, 174, 182, 196, 216, 362-365, 391, 432, 620-623
plugins/authentication/qsauth.py                34       1  97.06%   91
plugins/authentication/sas_auth.py             134       4  97.01%   135, 141, 177, 224
plugins/authentication/token.py                141       9  93.62%   192, 229, 309-310, 358-362
plugins/authentication/token_exchange.py        36       3  91.67%   75, 114-115
plugins/crunch/__init__.py                       6       0  100.00%
plugins/crunch/base.py                          12       0  100.00%
plugins/crunch/filter_date.py                   47       0  100.00%
plugins/crunch/filter_latest_intersect.py       52       6  88.46%   87-88, 95-96, 98-102
plugins/crunch/filter_latest_tpl_name.py        35       0  100.00%
plugins/crunch/filter_overlap.py                66      10  84.85%   118-121, 137-161
plugins/crunch/filter_property.py               30       2  93.33%   81-84
plugins/download/__init__.py                     4       0  100.00%
plugins/download/aws.py                        426      43  89.91%   275, 309, 377-380, 412-413, 421-425, 534-537, 577-579, 583, 613-614, 620-624, 654, 721-733, 819, 836, 851, 883-884, 947, 973, 1018-1020, 1072
plugins/download/base.py                       300      27  91.00%   148, 178, 253-255, 400-401, 445, 463, 479, 556-560, 590, 625-626, 650-659, 718, 739, 761, 769
plugins/download/http.py                       584      72  87.67%   257, 272, 364-367, 370, 377-382, 414-415, 432, 447, 508, 541, 554, 568, 581-585, 601-606, 617, 636, 672-675, 696, 706, 713, 755, 877, 911, 943-952, 988, 1033-1038, 1047, 1062-1064, 1068, 1071, 1099, 1119, 1177, 1229, 1272-1273, 1285, 1295, 1351-1352, 1382, 1409, 1428, 1508-1509
plugins/search/__init__.py                      25       0  100.00%
plugins/search/base.py                         220      20  90.91%   119, 123, 147-153, 162, 228-231, 264, 314, 346, 367, 500, 585-588, 597
plugins/search/build_search_result.py          565      45  92.04%   258, 354, 435-441, 521-522, 571, 582-584, 608, 610, 675, 683-687, 707, 717, 743, 792, 817, 879-884, 943, 970, 973, 1081, 1216, 1231, 1234, 1259, 1381, 1396, 1437-1438, 1482, 1491-1493, 1548, 1594
plugins/search/cop_ghsl.py                     408      28  93.14%   72-73, 108-109, 173, 175, 217, 297, 313, 359, 383, 403, 424, 458, 474, 509, 538-539, 552-554, 565-567, 592, 612, 649, 653
plugins/search/cop_marine.py                   301      34  88.70%   56, 64-66, 82, 104, 106, 109, 175-176, 196, 220, 226, 230, 252-253, 261, 308, 318, 331, 339, 345-349, 366, 398-401, 416, 486, 498, 541-542
plugins/search/creodias_s3.py                   29       1  96.55%   59
plugins/search/csw.py                          120      12  90.00%   124, 168, 206, 217-228, 233
plugins/search/eumetsat_ds.py                   24       0  100.00%
plugins/search/geodes.py                        66       0  100.00%
plugins/search/oar.py                           84      15  82.14%   50, 57-60, 171-182, 188-190, 197
plugins/search/qssearch.py                     923      85  90.79%   372, 534-535, 558-559, 571-575, 875, 914, 944, 978, 1013, 1063, 1083, 1086-1087, 1117-1118, 1136, 1207, 1216, 1228-1238, 1247, 1262, 1271, 1284, 1307, 1348, 1422, 1460, 1533-1534, 1536-1541, 1543-1544, 1615, 1822, 1825, 1829-1830, 1849-1852, 1866, 1893, 1911-1925, 1936, 1985-1991, 1998, 2082, 2087-2088, 2118, 2238, 2242, 2253, 2278, 2291, 2299-2309, 2335
plugins/search/stac_list_assets.py              25       0  100.00%
plugins/search/static_stac_search.py            86      18  79.07%   99-127, 164, 168-171, 184
resources/__init__.py                            0       0  100.00%
resources/shp/__init__.py                        0       0  100.00%
types/__init__.py                              228      55  75.88%   59, 74-76, 97-101, 114-144, 181-188, 203, 213, 308, 341, 351-369, 374, 376, 378, 400, 405, 413, 423
types/bbox.py                                   39       0  100.00%
types/download_args.py                           9       0  100.00%
types/queryables.py                            152       1  99.34%   395
types/search_args.py                            71      18  74.65%   67-71, 78-95, 110
types/stac_extensions.py                       162       4  97.53%   455-461, 641
types/stac_metadata.py                         161      22  86.34%   98, 120, 153, 186-188, 202-216, 225-232, 259-262
utils/__init__.py                              662      21  96.83%   57, 214, 221, 237, 272, 349, 601-604, 644-645, 674, 1058-1061, 1129-1130, 1162, 1370, 1482, 1614
utils/cache.py                                  23       0  100.00%
utils/dates.py                                 191       1  99.48%   182
utils/deserialize.py                            74      10  86.49%   53, 55, 103, 108-109, 148, 162, 184-185, 191
utils/env.py                                     3       0  100.00%
utils/exceptions.py                             58       0  100.00%
utils/free_text_search.py                       65       2  96.92%   83, 91
utils/import_system.py                          28       6  78.57%   65-73
utils/logging.py                                42       3  92.86%   42-43, 61
utils/notebook.py                               43      12  72.09%   40, 57-61, 71-77, 85-86
utils/repr.py                                   38       0  100.00%
utils/requests.py                               55       6  89.09%   94, 110, 118-120, 128
utils/s3.py                                    307      24  92.18%   97-99, 104, 110, 116, 120, 133, 137, 303-304, 345, 361, 383, 605, 688-689, 751, 793-797, 851
utils/stac_reader.py                           113      42  62.83%   63-85, 101, 138, 154-159, 206-216, 226-256
utils/streamresponse.py                         91       4  95.60%   105, 165, 174, 186
utils/yaml.py                                   42       7  83.33%   49, 65, 70-74
TOTAL                                        12244    1022  91.65%

Diff against develop

Filename                                 Stmts    Miss  Cover
-------------------------------------  -------  ------  -------
cli.py                                      +1       0  +0.02%
config.py                                   +1       0  +0.02%
api/collection.py                           -1       0  -0.03%
api/search_result.py                        -1       0  -0.06%
api/product/metadata_mapping.py             +2       0  +0.02%
plugins/base.py                             +1       0  +0.20%
plugins/apis/ecmwf.py                       +4      +1  -0.58%
plugins/apis/usgs.py                        +2      +1  -0.40%
plugins/download/http.py                    +2      +1  -0.13%
plugins/search/build_search_result.py       +9      +4  -0.59%
plugins/search/cop_ghsl.py                  -2      +1  -0.27%
plugins/search/cop_marine.py                +4       0  +0.15%
plugins/search/csw.py                       +2       0  +0.17%
plugins/search/oar.py                       +2      +2  -2.01%
plugins/search/qssearch.py                 +12      +4  -0.32%
plugins/search/static_stac_search.py        +2      +1  -0.69%
types/stac_metadata.py                      +2       0  +0.18%
utils/__init__.py                           +2       0  +0.01%
utils/notebook.py                           -1      -1  +1.64%
TOTAL                                      +43     +14  -0.09%

Results for commit: a1f5588

Minimum allowed coverage is 70%

♻️ This comment has been updated with latest results

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant