gitflow-analytics 3.10.4__py3-none-any.whl → 3.10.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.
@@ -1,4 +1,4 @@
1
1
  """Version information for gitflow-analytics."""
2
2
 
3
- __version__ = "3.10.4"
3
+ __version__ = "3.10.6"
4
4
  __version_info__ = tuple(int(x) for x in __version__.split("."))
gitflow_analytics/cli.py CHANGED
@@ -628,6 +628,27 @@ def analyze(
628
628
 
629
629
  cfg = ConfigLoader.load(config)
630
630
 
631
+ # Helper function to check if qualitative analysis is enabled
632
+ # Supports both top-level cfg.qualitative and nested cfg.analysis.qualitative
633
+ def is_qualitative_enabled() -> bool:
634
+ """Check if qualitative analysis is enabled in either location."""
635
+ if cfg.qualitative and cfg.qualitative.enabled:
636
+ return True
637
+ return (
638
+ hasattr(cfg.analysis, "qualitative")
639
+ and cfg.analysis.qualitative
640
+ and cfg.analysis.qualitative.enabled
641
+ )
642
+
643
+ # Helper function to get qualitative config from either location
644
+ def get_qualitative_config():
645
+ """Get qualitative config from either top-level or nested location."""
646
+ if cfg.qualitative:
647
+ return cfg.qualitative
648
+ if hasattr(cfg.analysis, "qualitative") and cfg.analysis.qualitative:
649
+ return cfg.analysis.qualitative
650
+ return None
651
+
631
652
  # Apply CLI overrides for PM integration
632
653
  if disable_pm:
633
654
  # Disable PM integration if explicitly requested
@@ -2974,9 +2995,8 @@ def analyze(
2974
2995
  # Perform qualitative analysis if enabled
2975
2996
  qualitative_results = []
2976
2997
  qual_cost_stats = None
2977
- if (
2978
- enable_qualitative or qualitative_only or (cfg.qualitative and cfg.qualitative.enabled)
2979
- ) and cfg.qualitative:
2998
+ qual_config = get_qualitative_config()
2999
+ if (enable_qualitative or qualitative_only or is_qualitative_enabled()) and qual_config:
2980
3000
  if display:
2981
3001
  display.print_status("Performing qualitative analysis...", "info")
2982
3002
  else:
@@ -2988,7 +3008,7 @@ def analyze(
2988
3008
 
2989
3009
  # Initialize qualitative analysis components
2990
3010
  qual_db = Database(cfg.cache.directory / "qualitative.db")
2991
- qual_processor = QualitativeProcessor(cfg.qualitative, qual_db)
3011
+ qual_processor = QualitativeProcessor(qual_config, qual_db)
2992
3012
 
2993
3013
  # Validate setup
2994
3014
  is_valid, issues = qual_processor.validate_setup()
@@ -3143,8 +3163,8 @@ def analyze(
3143
3163
  display.print_status("Continuing with standard analysis...", "info")
3144
3164
  else:
3145
3165
  click.echo(" ⏭️ Continuing with standard analysis...")
3146
- elif enable_qualitative and not cfg.qualitative:
3147
- warning_msg = "Qualitative analysis requested but not configured in config file\n\nAdd a 'qualitative:' section to your configuration"
3166
+ elif enable_qualitative and not get_qualitative_config():
3167
+ warning_msg = "Qualitative analysis requested but not configured in config file\n\nAdd a 'qualitative:' section (top-level or under 'analysis:') to your configuration"
3148
3168
  if display:
3149
3169
  display.show_warning(warning_msg)
3150
3170
  else:
@@ -4085,12 +4105,12 @@ def analyze(
4085
4105
  )
4086
4106
  else:
4087
4107
  # Show note about token tracking when qualitative analysis is not configured
4088
- if not (enable_qualitative or (cfg.qualitative and cfg.qualitative.enabled)):
4108
+ if not (enable_qualitative or is_qualitative_enabled()):
4089
4109
  click.echo(
4090
4110
  "\n💡 Note: Token/cost tracking is only available with qualitative analysis enabled."
4091
4111
  )
4092
4112
  click.echo(
4093
- " Add 'qualitative:' section to your config to enable detailed LLM cost tracking."
4113
+ " Add 'qualitative:' section (top-level or under 'analysis:') to your config to enable detailed LLM cost tracking."
4094
4114
  )
4095
4115
 
4096
4116
  # Display cache statistics in simple format
@@ -258,7 +258,14 @@ class ConfigLoader:
258
258
  jira_integration_config = cls._process_jira_integration_config(
259
259
  data.get("jira_integration", {})
260
260
  )
261
- qualitative_config = cls._process_qualitative_config(data.get("qualitative", {}))
261
+
262
+ # Check for qualitative config in both top-level and nested under analysis
263
+ # Prioritize top-level for backward compatibility, but support nested location
264
+ qualitative_data = data.get("qualitative", {})
265
+ if not qualitative_data and "analysis" in data:
266
+ qualitative_data = data["analysis"].get("qualitative", {})
267
+ qualitative_config = cls._process_qualitative_config(qualitative_data)
268
+
262
269
  pm_config = cls._process_pm_config(data.get("pm", {}))
263
270
  pm_integration_config = cls._process_pm_integration_config(data.get("pm_integration", {}))
264
271
 
@@ -536,6 +543,12 @@ class ConfigLoader:
536
543
  BranchAnalysisConfig(**branch_data) if branch_data else BranchAnalysisConfig()
537
544
  )
538
545
 
546
+ # Process qualitative configuration (support nested under analysis)
547
+ qualitative_data = analysis_data.get("qualitative", {})
548
+ qualitative_config = (
549
+ cls._process_qualitative_config(qualitative_data) if qualitative_data else None
550
+ )
551
+
539
552
  # Process aliases file and manual identity mappings
540
553
  manual_mappings = list(analysis_data.get("identity", {}).get("manual_mappings", []))
541
554
  aliases_file_path = None
@@ -595,6 +608,7 @@ class ConfigLoader:
595
608
  commit_classification=commit_classification_config,
596
609
  llm_classification=llm_classification_config,
597
610
  security=analysis_data.get("security", {}),
611
+ qualitative=qualitative_config,
598
612
  )
599
613
 
600
614
  @classmethod
@@ -316,6 +316,7 @@ class AnalysisConfig:
316
316
  )
317
317
  llm_classification: LLMClassificationConfig = field(default_factory=LLMClassificationConfig)
318
318
  security: Optional[dict[str, Any]] = field(default_factory=dict) # Security configuration
319
+ qualitative: Optional["QualitativeConfig"] = None # Nested qualitative config support
319
320
 
320
321
 
321
322
  @dataclass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitflow-analytics
3
- Version: 3.10.4
3
+ Version: 3.10.6
4
4
  Summary: Analyze Git repositories for developer productivity insights
5
5
  Author-email: Bob Matyas <bobmatnyc@gmail.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  gitflow_analytics/__init__.py,sha256=W3Jaey5wuT1nBPehVLTIRkVIyBa5jgYOlBKc_UFfh-4,773
2
- gitflow_analytics/_version.py,sha256=Ern03L7_bWd8JxtBPPk3W30NHPMvxVnsv_nDZU6D_sM,138
3
- gitflow_analytics/cli.py,sha256=pYW6V0b6SRa3-NyOmXGQhf5emcKHUHgOVL2PFOAS8LQ,273331
2
+ gitflow_analytics/_version.py,sha256=EZYcvAFHOt8s3T1uFte5WRCRLCJA_e9z4u9hjkDwMvE,138
3
+ gitflow_analytics/cli.py,sha256=j-xjxPWTViFVullTUwVY3qJqwPXBZOEwgADwAvq_xVA,274357
4
4
  gitflow_analytics/config.py,sha256=XRuxvzLWyn_ML7mDCcuZ9-YFNAEsnt33vIuWxQQ_jxg,1033
5
5
  gitflow_analytics/constants.py,sha256=GXEncUJS9ijOI5KWtQCTANwdqxPfXpw-4lNjhaWTKC4,2488
6
6
  gitflow_analytics/verify_activity.py,sha256=aRQnmypf5NDasXudf2iz_WdJnCWtwlbAiJ5go0DJLSU,27050
@@ -16,10 +16,10 @@ gitflow_analytics/cli_wizards/run_launcher.py,sha256=J6G_C7IqxPg7_GhAfbV99D1dIIW
16
16
  gitflow_analytics/config/__init__.py,sha256=KziRIbBJctB5LOLcKLzELWA1rXwjS6-C2_DeM_hT9rM,1133
17
17
  gitflow_analytics/config/aliases.py,sha256=z9F0X6qbbF544Tw7sHlOoBj5mpRSddMkCpoKLzvVzDU,10960
18
18
  gitflow_analytics/config/errors.py,sha256=IBKhAIwJ4gscZFnLDyE3jEp03wn2stPR7JQJXNSIfok,10386
19
- gitflow_analytics/config/loader.py,sha256=EiksTB1Uqey63FxIvuud_kMdab3sNDfuICE_RwMLYFA,37290
19
+ gitflow_analytics/config/loader.py,sha256=Rjr3YyD6iFZsS0MRGy9w_GN8Q0CuDOIab-oBDpuc-Q8,37951
20
20
  gitflow_analytics/config/profiles.py,sha256=yUjFAWW6uzOUdi5qlPE-QV9681HigyrLiSJFpL8X9A0,7967
21
21
  gitflow_analytics/config/repository.py,sha256=u7JHcKvqmXOl3i7EmNUfJ6wtjzElxPMyXRkATnVyQ0I,4685
22
- gitflow_analytics/config/schema.py,sha256=tzXyckIY8RNRpS9ez9iBuVtZMe-WXjBBjsp9Pm-aetU,17088
22
+ gitflow_analytics/config/schema.py,sha256=CR9swU5LaQGBtcI9KgHzG1t17cas00ECI22LwJiRgqs,17179
23
23
  gitflow_analytics/config/validator.py,sha256=l7AHjXYJ8wEmyA1rn2WiItZXtAiRb9YBLjFCDl53qKM,5907
24
24
  gitflow_analytics/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  gitflow_analytics/core/analyzer.py,sha256=59kGObzjziOb8geFyZMKCUvWmo3hcXE0eTgrjYEc1XA,58736
@@ -120,9 +120,9 @@ gitflow_analytics/training/model_loader.py,sha256=xGZLSopGxDhC--2XN6ytRgi2CyjOKY
120
120
  gitflow_analytics/training/pipeline.py,sha256=PQegTk_-OsPexVyRDfiy-3Df-7pcs25C4vPASr-HT9E,19951
121
121
  gitflow_analytics/ui/__init__.py,sha256=UBhYhZMvwlSrCuGWjkIdoP2zNbiQxOHOli-I8mqIZUE,441
122
122
  gitflow_analytics/ui/progress_display.py,sha256=3xJnCOSs1DRVAfS-rTu37EsLfWDFW5-mbv-bPS9NMm4,59182
123
- gitflow_analytics-3.10.4.dist-info/licenses/LICENSE,sha256=xwvSwY1GYXpRpmbnFvvnbmMwpobnrdN9T821sGvjOY0,1066
124
- gitflow_analytics-3.10.4.dist-info/METADATA,sha256=OASbKCl7rhlw1eGy1I2zkKOUNHkMHgs52przeGpZ4Fc,36831
125
- gitflow_analytics-3.10.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
126
- gitflow_analytics-3.10.4.dist-info/entry_points.txt,sha256=ZOsX0GLsnMysp5FWPOfP_qyoS7WJ8IgcaDFDxWBYl1g,98
127
- gitflow_analytics-3.10.4.dist-info/top_level.txt,sha256=CQyxZXjKvpSB1kgqqtuE0PCRqfRsXZJL8JrYpJKtkrk,18
128
- gitflow_analytics-3.10.4.dist-info/RECORD,,
123
+ gitflow_analytics-3.10.6.dist-info/licenses/LICENSE,sha256=xwvSwY1GYXpRpmbnFvvnbmMwpobnrdN9T821sGvjOY0,1066
124
+ gitflow_analytics-3.10.6.dist-info/METADATA,sha256=We2H93azJZOCshGIrmnL7RnufmwKnafTxd7wUpOVatw,36831
125
+ gitflow_analytics-3.10.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
126
+ gitflow_analytics-3.10.6.dist-info/entry_points.txt,sha256=ZOsX0GLsnMysp5FWPOfP_qyoS7WJ8IgcaDFDxWBYl1g,98
127
+ gitflow_analytics-3.10.6.dist-info/top_level.txt,sha256=CQyxZXjKvpSB1kgqqtuE0PCRqfRsXZJL8JrYpJKtkrk,18
128
+ gitflow_analytics-3.10.6.dist-info/RECORD,,