greenmining 1.1.4__py3-none-any.whl → 1.1.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
greenmining/__init__.py CHANGED
@@ -9,7 +9,7 @@ from greenmining.gsf_patterns import (
9
9
  is_green_aware,
10
10
  )
11
11
 
12
- __version__ = "1.1.4"
12
+ __version__ = "1.1.6"
13
13
 
14
14
 
15
15
  def fetch_repositories(
@@ -51,6 +51,8 @@ def analyze_repositories(
51
51
  include_source_code: bool = False,
52
52
  ssh_key_path: str = None,
53
53
  github_token: str = None,
54
+ since_date: str = None,
55
+ to_date: str = None,
54
56
  ):
55
57
  # Analyze multiple repositories from URLs.
56
58
  # Args:
@@ -64,8 +66,20 @@ def analyze_repositories(
64
66
  # include_source_code: Include source code before/after in results
65
67
  # ssh_key_path: SSH key path for private repositories
66
68
  # github_token: GitHub token for private HTTPS repositories
69
+ # since_date: Analyze commits from this date (YYYY-MM-DD string)
70
+ # to_date: Analyze commits up to this date (YYYY-MM-DD string)
67
71
  from greenmining.services.local_repo_analyzer import LocalRepoAnalyzer
68
72
 
73
+ kwargs = {}
74
+ if since_date:
75
+ from datetime import datetime
76
+
77
+ kwargs["since_date"] = datetime.strptime(since_date, "%Y-%m-%d")
78
+ if to_date:
79
+ from datetime import datetime
80
+
81
+ kwargs["to_date"] = datetime.strptime(to_date, "%Y-%m-%d")
82
+
69
83
  analyzer = LocalRepoAnalyzer(
70
84
  max_commits=max_commits,
71
85
  energy_tracking=energy_tracking,
@@ -74,6 +88,7 @@ def analyze_repositories(
74
88
  include_source_code=include_source_code,
75
89
  ssh_key_path=ssh_key_path,
76
90
  github_token=github_token,
91
+ **kwargs,
77
92
  )
78
93
 
79
94
  return analyzer.analyze_repositories(
@@ -50,7 +50,8 @@ class StatisticalAnalyzer:
50
50
  def temporal_trend_analysis(self, commits_df: pd.DataFrame) -> Dict[str, Any]:
51
51
  # Analyze temporal trends in green awareness.
52
52
  # Prepare time series data
53
- commits_df["date"] = pd.to_datetime(commits_df["date"])
53
+ commits_df["date"] = pd.to_datetime(commits_df["date"], utc=True, errors="coerce")
54
+ commits_df["date"] = commits_df["date"].dt.tz_localize(None)
54
55
  commits_df = commits_df.sort_values("date")
55
56
 
56
57
  # Monthly aggregation
@@ -42,6 +42,14 @@ class EnergyMetrics:
42
42
  start_time: Optional[datetime] = None
43
43
  end_time: Optional[datetime] = None
44
44
 
45
+ @property
46
+ def energy_joules(self) -> float:
47
+ return self.joules
48
+
49
+ @property
50
+ def average_power_watts(self) -> float:
51
+ return self.watts_avg
52
+
45
53
  def to_dict(self) -> Dict[str, Any]:
46
54
  # Convert to dictionary.
47
55
  return {
@@ -204,6 +204,8 @@ class LocalRepoAnalyzer:
204
204
  method_level_analysis: bool = False,
205
205
  include_source_code: bool = False,
206
206
  process_metrics: str = "standard",
207
+ since_date: Optional[datetime] = None,
208
+ to_date: Optional[datetime] = None,
207
209
  ):
208
210
  # Initialize the local repository analyzer.
209
211
  # Args:
@@ -224,6 +226,8 @@ class LocalRepoAnalyzer:
224
226
  self.clone_path.mkdir(parents=True, exist_ok=True)
225
227
  self.max_commits = max_commits
226
228
  self.days_back = days_back
229
+ self.since_date = since_date
230
+ self.to_date = to_date
227
231
  self.skip_merges = skip_merges
228
232
  self.compute_process_metrics = compute_process_metrics
229
233
  self.cleanup_after = cleanup_after
@@ -446,7 +450,7 @@ class LocalRepoAnalyzer:
446
450
  auth_url = self._prepare_auth_url(url)
447
451
 
448
452
  # Calculate date range
449
- since_date = datetime.now() - timedelta(days=self.days_back)
453
+ since_date = self.since_date or (datetime.now() - timedelta(days=self.days_back))
450
454
 
451
455
  # Configure PyDriller Repository
452
456
  repo_config = {
@@ -454,6 +458,8 @@ class LocalRepoAnalyzer:
454
458
  "since": since_date,
455
459
  "only_no_merge": self.skip_merges,
456
460
  }
461
+ if self.to_date:
462
+ repo_config["to"] = self.to_date
457
463
 
458
464
  # Clone to specific path if needed
459
465
  local_path = self.clone_path / repo_name
@@ -464,13 +470,16 @@ class LocalRepoAnalyzer:
464
470
 
465
471
  colored_print(f" Cloning to: {local_path}", "cyan")
466
472
 
467
- # Phase 2.2: Start energy measurement if enabled
473
+ # Phase 2.2: Start energy measurement if enabled (fresh meter per repo)
468
474
  energy_result = None
469
- if self.energy_tracking and self._energy_meter:
475
+ energy_meter = None
476
+ if self.energy_tracking:
470
477
  try:
471
- self._energy_meter.start()
472
- except Exception as e:
473
- colored_print(f" Warning: Energy measurement start failed: {e}", "yellow")
478
+ from greenmining.energy.base import get_energy_meter
479
+ energy_meter = get_energy_meter(self.energy_backend)
480
+ energy_meter.start()
481
+ except Exception:
482
+ energy_meter = None
474
483
 
475
484
  commits_analyzed = []
476
485
  commit_count = 0
@@ -497,11 +506,11 @@ class LocalRepoAnalyzer:
497
506
  colored_print(f" Analyzed {len(commits_analyzed)} commits", "green")
498
507
 
499
508
  # Phase 2.2: Stop energy measurement
500
- if self.energy_tracking and self._energy_meter:
509
+ if energy_meter:
501
510
  try:
502
- energy_result = self._energy_meter.stop()
503
- except Exception as e:
504
- colored_print(f" Warning: Energy measurement stop failed: {e}", "yellow")
511
+ energy_result = energy_meter.stop()
512
+ except Exception:
513
+ pass
505
514
 
506
515
  # Compute process metrics if enabled
507
516
  process_metrics = {}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: greenmining
3
- Version: 1.1.4
3
+ Version: 1.1.6
4
4
  Summary: An empirical Python library for Mining Software Repositories (MSR) in Green IT research
5
5
  Author-email: Adam Bouafia <a.bouafia@student.vu.nl>
6
6
  License: MIT
@@ -73,7 +73,7 @@ An empirical Python library for Mining Software Repositories (MSR) in Green IT r
73
73
  - **Mine repositories at scale** - Fetch and analyze GitHub repositories via GraphQL API with configurable filters
74
74
  - **Batch analysis with parallelism** - Analyze multiple repositories concurrently with configurable worker pools
75
75
  - **Classify green commits** - Detect 122 sustainability patterns from the Green Software Foundation (GSF) catalog
76
- - **Analyze any repository by URL** - Direct PyDriller-based analysis with support for private repositories
76
+ - **Analyze any repository by URL** - Direct Git-based analysis with support for private repositories
77
77
  - **Measure energy consumption** - RAPL, CodeCarbon, and CPU Energy Meter backends for power profiling
78
78
  - **Carbon footprint reporting** - CO2 emissions calculation with 20+ country profiles and cloud region support
79
79
  - **Power regression detection** - Identify commits that increased energy consumption
@@ -685,7 +685,7 @@ config = Config(
685
685
  - **Pattern Detection**: 122 sustainability patterns across 15 categories from the GSF catalog
686
686
  - **Keyword Analysis**: 321 green software detection keywords
687
687
  - **Repository Fetching**: GraphQL API with date, star, and language filters
688
- - **URL-Based Analysis**: Direct PyDriller analysis from GitHub URLs (HTTPS and SSH)
688
+ - **URL-Based Analysis**: Direct Git-based analysis from GitHub URLs (HTTPS and SSH)
689
689
  - **Batch Processing**: Parallel analysis of multiple repositories with configurable workers
690
690
  - **Private Repository Support**: Authentication via SSH keys or GitHub tokens
691
691
  - **Energy Measurement**: RAPL, CodeCarbon, and CPU Energy Meter backends
@@ -695,7 +695,7 @@ config = Config(
695
695
  - **Version Power Comparison**: Compare power consumption across software versions with trend detection
696
696
  - **Method-Level Analysis**: Per-method complexity metrics via Lizard integration
697
697
  - **Source Code Access**: Before/after source code for refactoring detection
698
- - **Full Process Metrics**: All 8 PyDriller process metrics (ChangeSet, CodeChurn, CommitsCount, ContributorsCount, ContributorsExperience, HistoryComplexity, HunksCount, LinesCount)
698
+ - **Full Process Metrics**: All 8 process metrics (ChangeSet, CodeChurn, CommitsCount, ContributorsCount, ContributorsExperience, HistoryComplexity, HunksCount, LinesCount)
699
699
  - **Statistical Analysis**: Correlations, effect sizes, and temporal trends
700
700
  - **Multi-format Output**: Markdown reports, CSV exports, JSON data
701
701
  - **Web Dashboard**: Flask-based interactive visualization (`pip install greenmining[dashboard]`)
@@ -849,7 +849,8 @@ ruff check greenmining/ tests/
849
849
 
850
850
  - Python 3.9+
851
851
  - PyGithub >= 2.1.1
852
- - PyDriller >= 2.5
852
+ - gitpython >= 3.1.0
853
+ - lizard >= 1.17.0
853
854
  - pandas >= 2.2.0
854
855
 
855
856
  **Optional dependencies:**
@@ -1,4 +1,4 @@
1
- greenmining/__init__.py,sha256=f8971n5AONb3am4c0v2yuJ8kUTp4rVtIe-uawjENwEI,2909
1
+ greenmining/__init__.py,sha256=jkQOxpAJmEyUIt6LgwuGESxdSsDWGd0qv1Vrsa26YzM,3390
2
2
  greenmining/__main__.py,sha256=NYOVS7D4w2XDLn6SyXHXPKE5GrNGOeoWSTb_KazgK5c,590
3
3
  greenmining/__version__.py,sha256=xZc02a8bS3vUJlzh8k9RoxemB1irQmq_SpVVj6Cg5M0,62
4
4
  greenmining/config.py,sha256=M4a7AwM1ErCmOY0n5Vmyoo9HPblSkTZ-HD3k2YHzs4A,8340
@@ -9,7 +9,7 @@ greenmining/analyzers/code_diff_analyzer.py,sha256=1dk68R3O0RZG8gx1cm9B_UlZ1Uwyb
9
9
  greenmining/analyzers/metrics_power_correlator.py,sha256=qMKr4hSTzT0Un3vsGZNkPCp9TxyzdFwrhjw5M1IKOgk,5964
10
10
  greenmining/analyzers/power_regression.py,sha256=5pxs7IoTtGcwwX5KzGeM5hOm2I9Axr-0X4N_4007iMw,7387
11
11
  greenmining/analyzers/qualitative_analyzer.py,sha256=RcjOMLj_DPH869ey9J0uI7JK_krCefMhNkPLOJUDFF8,15391
12
- greenmining/analyzers/statistical_analyzer.py,sha256=DzWAcCyw42Ig3FIxTwPPBikgt2uzMdktxklonOYfnOk,7166
12
+ greenmining/analyzers/statistical_analyzer.py,sha256=rqLsRGuOHhxEMQAFx5dmWMHDgdb6ktL7CY3dAebQvpA,7262
13
13
  greenmining/analyzers/temporal_analyzer.py,sha256=JfTcAoI20oCFMehGrSRnDqhJTXI-RUbdCTMwDOTW9-g,14259
14
14
  greenmining/analyzers/version_power_analyzer.py,sha256=2P6zOqBg-ButtIhF-4cutiwD2Q1geMY49VFUghHXXoI,8119
15
15
  greenmining/controllers/__init__.py,sha256=UiAT6zBvC1z_9cJWfzq1cLA0I4r9b2vURHipj8oDczI,180
@@ -17,7 +17,7 @@ greenmining/controllers/repository_controller.py,sha256=DM9BabUAwZJARGngCk_4wEYP
17
17
  greenmining/dashboard/__init__.py,sha256=Ig_291-hLrH9k3rV0whhQ1EkhiaRR8ciHiJ5s5OCBf4,141
18
18
  greenmining/dashboard/app.py,sha256=Hk6_i2qmcg6SGW7UzxglEIvUBJiloRA-hMYI-YSORcA,8604
19
19
  greenmining/energy/__init__.py,sha256=GoCYh7hitWBoPMtan1HF1yezCHi7o4sa_YUJgGkeJc8,558
20
- greenmining/energy/base.py,sha256=mVdp-E04KWu3UnHFL61pzrI-OP-KsUshAmXHwgsJkRU,5749
20
+ greenmining/energy/base.py,sha256=3hIPgc4B0Nz9V7DTh2Xd6trDRtmozUBBpa5UWRuWzcw,5918
21
21
  greenmining/energy/carbon_reporter.py,sha256=bKIFlLhHfYzI4DBu_ff4GW1Psz4oSCAF4NmzQb-EShA,8298
22
22
  greenmining/energy/codecarbon_meter.py,sha256=HyQptyEaS1ZMu_qdxg0Tyuly1PCmmbbNwwYX8qYsTs4,4927
23
23
  greenmining/energy/cpu_meter.py,sha256=mhEG3Y7fjz3wV5lojcYeFXvCXXgmelGQaBfN2q7yTNc,5007
@@ -35,10 +35,10 @@ greenmining/services/data_aggregator.py,sha256=TsFT0oGOnnHk0QGZ1tT6ZhKGc5X1H1D1u
35
35
  greenmining/services/data_analyzer.py,sha256=f0nlJkPAclHHCzzTyQW5bjhYrgE0XXiR1x7_o3fJaDs,9732
36
36
  greenmining/services/github_fetcher.py,sha256=sdkS-LhHmX7mgMdlClCwEUVnZrItc0Pt6FVtlWk5iLU,106
37
37
  greenmining/services/github_graphql_fetcher.py,sha256=ZklXdEAc60KeFL83zRYMwW_-2OwMKpfPY7Wrifl0D50,11539
38
- greenmining/services/local_repo_analyzer.py,sha256=5DMN9RIyGXNdsOlIDV4Mp0fPavbB69oBA9us17P5cNo,24668
38
+ greenmining/services/local_repo_analyzer.py,sha256=pnH_Hf3GjCFovurEl2uZgOgD3qjqcsP2K1QnKHddkSY,24903
39
39
  greenmining/services/reports.py,sha256=Vrw_pBNmVw2mTAf1dpcAqjBe6gXv-O4w_XweoVTt7L8,23392
40
- greenmining-1.1.4.dist-info/licenses/LICENSE,sha256=M7ma3JHGeiIZIs3ea0HTcFl_wLFPX2NZElUliYs4bCA,1083
41
- greenmining-1.1.4.dist-info/METADATA,sha256=YaFtuN9JviTEk3q6vAswjLeW6nYLRrGuFglQhbsGP68,30806
42
- greenmining-1.1.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
43
- greenmining-1.1.4.dist-info/top_level.txt,sha256=nreXgXxZIWI-42yQknQ0HXtUrFnzZ8N1ra4Mdy2KcsI,12
44
- greenmining-1.1.4.dist-info/RECORD,,
40
+ greenmining-1.1.6.dist-info/licenses/LICENSE,sha256=M7ma3JHGeiIZIs3ea0HTcFl_wLFPX2NZElUliYs4bCA,1083
41
+ greenmining-1.1.6.dist-info/METADATA,sha256=ADh-CwQLjdVv3P3BdMI8Ao50u1dPngilhoCTcX-Hr7M,30811
42
+ greenmining-1.1.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
43
+ greenmining-1.1.6.dist-info/top_level.txt,sha256=nreXgXxZIWI-42yQknQ0HXtUrFnzZ8N1ra4Mdy2KcsI,12
44
+ greenmining-1.1.6.dist-info/RECORD,,