Skip to content

Commit 2a48474

Browse files
authored
2 parents c407630 + d7e5626 commit 2a48474

File tree

5 files changed

+77
-16
lines changed

5 files changed

+77
-16
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ trustable spdx.xml \
5454
--grimoirelab-user user --grimoirelab-password password \
5555
--opensearch-url https://admin:[email protected]:9200 \
5656
--opensearch-index events \
57+
--from-date 2024-01-01 --to-date 2025-01-01 \
5758
--repository-timeout 3600
5859
--code-file-pattern "\.py$|\.js$" \
5960
--binary-file-pattern "\.exe$|\.tar$" \
@@ -106,3 +107,11 @@ This is an example of a valid SPDX file:
106107
This is the list of the metrics generated by this tool:
107108

108109
- Number of commits per repository
110+
- Number of developers per repository
111+
- Number of developers producing up to 50% of the total contributions
112+
- Number of companies producing up to 50% of the total number of code contributions
113+
- File type metrics (code, binaries or other)
114+
- Commit side metrics (added lines and removed lines)
115+
- Message size metrics (total, mean and median)
116+
- Frequency metrics for commits (week, month and year)
117+
- Developer categories (core, regular and casual)

tests/end_to_end/test_cli.py

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def test_metrics(self):
5050
"--output",
5151
self.temp_file.name,
5252
"--from-date=2000-01-01",
53+
"--to-date=2025-01-01",
5354
],
5455
)
5556
self.assertEqual(result.exit_code, 0)
@@ -82,7 +83,10 @@ def test_metrics(self):
8283
self.assertEqual(quickstart_metrics["developer_categories_core"], 3)
8384
self.assertEqual(quickstart_metrics["developer_categories_regular"], 13)
8485
self.assertEqual(quickstart_metrics["developer_categories_casual"], 9)
85-
self.assertAlmostEqual(quickstart_metrics["commits_week_mean"], 0.06418, delta=0.1)
86+
# From 2000 to 2025 there are 9132 days
87+
self.assertAlmostEqual(quickstart_metrics["commits_per_week"], 164 / (9132 / 7), delta=0.1)
88+
self.assertAlmostEqual(quickstart_metrics["commits_per_month"], 164 / (9132 / 30), delta=0.1)
89+
self.assertAlmostEqual(quickstart_metrics["commits_per_year"], 164 / (9132 / 365), delta=0.1)
8690

8791
self.assertIn("SPDXRef-angular-seed", metrics["packages"])
8892
self.assertEqual(
@@ -104,7 +108,10 @@ def test_metrics(self):
104108
self.assertEqual(angular_metrics["developer_categories_core"], 16)
105109
self.assertEqual(angular_metrics["developer_categories_regular"], 31)
106110
self.assertEqual(angular_metrics["developer_categories_casual"], 11)
107-
self.assertAlmostEqual(angular_metrics["commits_week_mean"], 0.08101, delta=0.1)
111+
# From 2000 to 2025 there are 9132 days
112+
self.assertAlmostEqual(angular_metrics["commits_per_week"], 207 / (9132 / 7), delta=0.1)
113+
self.assertAlmostEqual(angular_metrics["commits_per_month"], 207 / (9132 / 30), delta=0.1)
114+
self.assertAlmostEqual(angular_metrics["commits_per_year"], 207 / (9132 / 365), delta=0.1)
108115

109116
def test_from_date(self):
110117
"""Check if it returns the number of commits of one repository from a particular date"""
@@ -127,6 +134,7 @@ def test_from_date(self):
127134
"--output",
128135
self.temp_file.name,
129136
"--from-date=2017-01-01",
137+
"--to-date=2025-01-01",
130138
],
131139
)
132140
self.assertEqual(result.exit_code, 0)
@@ -159,7 +167,10 @@ def test_from_date(self):
159167
self.assertEqual(quickstart_metrics["developer_categories_core"], 3)
160168
self.assertEqual(quickstart_metrics["developer_categories_regular"], 3)
161169
self.assertEqual(quickstart_metrics["developer_categories_casual"], 2)
162-
self.assertAlmostEqual(quickstart_metrics["commits_week_mean"], 0.00861, delta=0.1)
170+
# From 2017 to 2025 there are 2922 days
171+
self.assertAlmostEqual(quickstart_metrics["commits_per_week"], 22 / (2922 / 7), delta=0.1)
172+
self.assertAlmostEqual(quickstart_metrics["commits_per_month"], 22 / (2922 / 30), delta=0.1)
173+
self.assertAlmostEqual(quickstart_metrics["commits_per_year"], 22 / (2922 / 365), delta=0.1)
163174

164175
self.assertIn("SPDXRef-angular-seed", metrics["packages"])
165176
self.assertEqual(
@@ -181,7 +192,10 @@ def test_from_date(self):
181192
self.assertEqual(angular_metrics["developer_categories_core"], 1)
182193
self.assertEqual(angular_metrics["developer_categories_regular"], 2)
183194
self.assertEqual(angular_metrics["developer_categories_casual"], 1)
184-
self.assertAlmostEqual(angular_metrics["commits_week_mean"], 0.0043, delta=0.1)
195+
# From 2017 to 2025 there are 2922 days
196+
self.assertAlmostEqual(angular_metrics["commits_per_week"], 11 / (2922 / 7), delta=0.1)
197+
self.assertAlmostEqual(angular_metrics["commits_per_month"], 11 / (2922 / 30), delta=0.1)
198+
self.assertAlmostEqual(angular_metrics["commits_per_year"], 11 / (2922 / 365), delta=0.1)
185199

186200
def test_to_date(self):
187201
"""Check if it returns the number of commits of one repository up to a particular date"""
@@ -237,7 +251,10 @@ def test_to_date(self):
237251
self.assertEqual(quickstart_metrics["developer_categories_core"], 3)
238252
self.assertEqual(quickstart_metrics["developer_categories_regular"], 9)
239253
self.assertEqual(quickstart_metrics["developer_categories_casual"], 8)
240-
self.assertAlmostEqual(quickstart_metrics["commits_week_mean"], 0.003266620657925006, delta=0.1)
254+
# From 2000 to 2017 there are 6210 days
255+
self.assertAlmostEqual(quickstart_metrics["commits_per_week"], 142 / (6210 / 7), delta=0.1)
256+
self.assertAlmostEqual(quickstart_metrics["commits_per_month"], 142 / (6210 / 30), delta=0.1)
257+
self.assertAlmostEqual(quickstart_metrics["commits_per_year"], 142 / (6210 / 365), delta=0.1)
241258

242259
self.assertIn("SPDXRef-angular-seed", metrics["packages"])
243260
self.assertEqual(
@@ -259,7 +276,10 @@ def test_to_date(self):
259276
self.assertEqual(angular_metrics["developer_categories_core"], 16)
260277
self.assertEqual(angular_metrics["developer_categories_regular"], 30)
261278
self.assertEqual(angular_metrics["developer_categories_casual"], 10)
262-
self.assertAlmostEqual(angular_metrics["commits_week_mean"], 0.0045088566827697265, delta=0.1)
279+
# From 2000 to 2017 there are 6210 days
280+
self.assertAlmostEqual(angular_metrics["commits_per_week"], 196 / (6210 / 7), delta=0.1)
281+
self.assertAlmostEqual(angular_metrics["commits_per_month"], 196 / (6210 / 30), delta=0.1)
282+
self.assertAlmostEqual(angular_metrics["commits_per_year"], 196 / (6210 / 365), delta=0.1)
263283

264284
def test_duplicate_repo(self):
265285
"""Check if it ignores duplicated URLs"""
@@ -282,6 +302,7 @@ def test_duplicate_repo(self):
282302
"--output",
283303
self.temp_file.name,
284304
"--from-date=2000-01-01",
305+
"--to-date=2025-01-01",
285306
],
286307
)
287308
self.assertEqual(result.exit_code, 0)
@@ -315,7 +336,10 @@ def test_duplicate_repo(self):
315336
self.assertEqual(quickstart_metrics["developer_categories_core"], 3)
316337
self.assertEqual(quickstart_metrics["developer_categories_regular"], 13)
317338
self.assertEqual(quickstart_metrics["developer_categories_casual"], 9)
318-
self.assertAlmostEqual(quickstart_metrics["commits_week_mean"], 0.06418, delta=0.1)
339+
# From 2000 to 2025 there are 9132 days
340+
self.assertAlmostEqual(quickstart_metrics["commits_per_week"], 164 / (9132 / 7), delta=0.1)
341+
self.assertAlmostEqual(quickstart_metrics["commits_per_month"], 164 / (9132 / 30), delta=0.1)
342+
self.assertAlmostEqual(quickstart_metrics["commits_per_year"], 164 / (9132 / 365), delta=0.1)
319343

320344
def test_non_git_repo(self):
321345
"""Check if it flags non-git dependencies"""
@@ -338,6 +362,7 @@ def test_non_git_repo(self):
338362
"--output",
339363
self.temp_file.name,
340364
"--from-date=2000-01-01",
365+
"--to-date=2025-01-01",
341366
],
342367
)
343368
self.assertEqual(result.exit_code, 0)
@@ -371,7 +396,10 @@ def test_non_git_repo(self):
371396
self.assertEqual(quickstart_metrics["developer_categories_core"], 3)
372397
self.assertEqual(quickstart_metrics["developer_categories_regular"], 13)
373398
self.assertEqual(quickstart_metrics["developer_categories_casual"], 9)
374-
self.assertAlmostEqual(quickstart_metrics["commits_week_mean"], 0.06418, delta=0.1)
399+
# From 2000 to 2025 there are 9132 days
400+
self.assertAlmostEqual(quickstart_metrics["commits_per_week"], 164 / (9132 / 7), delta=0.1)
401+
self.assertAlmostEqual(quickstart_metrics["commits_per_month"], 164 / (9132 / 30), delta=0.1)
402+
self.assertAlmostEqual(quickstart_metrics["commits_per_year"], 164 / (9132 / 365), delta=0.1)
375403

376404
self.assertIn("SPDXRef-sql-dk", metrics["packages"])
377405
self.assertEqual(metrics["packages"]["SPDXRef-sql-dk"]["metrics"], None)

tests/unit/test_metrics.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,23 @@ def test_message_size_metrics(self):
164164
self.assertAlmostEqual(metrics["mean"], 210.11, delta=0.1)
165165
self.assertEqual(metrics["median"], 229)
166166

167-
def test_get_commits_week_mean(self):
167+
def test_get_commits_frequency(self):
168168
"""Test whether the average (mean) commits per week is calculated correctly"""
169169

170170
self.analyzer.process_events(self.events)
171-
avg = self.analyzer.get_commits_week_mean(days_interval=30)
172-
self.assertAlmostEqual(avg, 9 / 30 / 7, delta=0.1)
171+
metrics = self.analyzer.get_commit_frequency_metrics(days_interval=30)
172+
self.assertAlmostEqual(metrics["week"], 9 / (30 / 7), delta=0.1)
173+
self.assertAlmostEqual(metrics["month"], 9, delta=0.1)
174+
self.assertIsNone(metrics["year"])
175+
176+
def test_get_all_commits_frequency(self):
177+
"""Test whether the average (mean) commits per week and year is calculated correctly"""
178+
179+
self.analyzer.process_events(self.events)
180+
metrics = self.analyzer.get_commit_frequency_metrics(days_interval=365)
181+
self.assertAlmostEqual(metrics["week"], 9 / (365 / 7), delta=0.1)
182+
self.assertAlmostEqual(metrics["month"], 9 / (365 / 30), delta=0.1)
183+
self.assertAlmostEqual(metrics["year"], 9, delta=0.1)
173184

174185
def test_get_developer_categories(self):
175186
"""Test if the developer categories are calculated correctly"""

trustable_cli/cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@
7373
@click.option(
7474
"--to-date",
7575
type=click.DateTime(formats=["%Y-%m-%d"]),
76-
help="End date",
76+
help="End date, by default today",
77+
default=datetime.datetime.today().strftime("%Y-%m-%d"),
7778
)
7879
@click.option("--verify-certs", is_flag=True, default=False, help="Verify SSL/TLS certificates")
7980
@click.option("--verbose", is_flag=True, default=False, help="Increase output verbosity")

trustable_cli/metrics.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,25 @@ def get_message_size_metrics(self):
147147
}
148148
return metrics
149149

150-
def get_commits_week_mean(self, days_interval: int):
150+
def get_commit_frequency_metrics(self, days_interval: int):
151151
"""
152-
Get the average (mean) number of commits per week
152+
Get the average (mean) number of commits per week, month and
153+
year if the days of interval is greater than the metrics interval.
153154
154155
:param days_interval: Interval of days to calculate the mean
155156
"""
156-
return self.total_commits / days_interval / 7
157+
metrics = {"week": None, "month": None, "year": None}
158+
159+
if days_interval >= 7:
160+
metrics["week"] = self.total_commits / (days_interval / 7)
161+
162+
if days_interval >= 30:
163+
metrics["month"] = self.total_commits / (days_interval / 30)
164+
165+
if days_interval >= 365:
166+
metrics["year"] = self.total_commits / (days_interval / 365)
167+
168+
return metrics
157169

158170
def get_developer_categories(self):
159171
"""Return the number of core, regular and casual developers"""
@@ -261,14 +273,14 @@ def get_repository_metrics(
261273
days = (to_date - from_date).days
262274
else:
263275
days = 365
264-
metrics["metrics"]["commits_week_mean"] = analyzer.get_commits_week_mean(days)
265276

266277
# Flatten two-level metrics
267278
metrics_to_flatten = {
268279
"file_types": analyzer.get_file_type_metrics(),
269280
"commit_size": analyzer.get_commit_size_metrics(),
270281
"message_size": analyzer.get_message_size_metrics(),
271282
"developer_categories": analyzer.get_developer_categories(),
283+
"commits_per": analyzer.get_commit_frequency_metrics(days),
272284
}
273285

274286
for prefix, metrics_set in metrics_to_flatten.items():

0 commit comments

Comments
 (0)