gitflow-analytics 3.3.0__py3-none-any.whl → 3.4.7__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.
- gitflow_analytics/_version.py +1 -1
- gitflow_analytics/cli.py +164 -15
- gitflow_analytics/cli_wizards/__init__.py +10 -0
- gitflow_analytics/cli_wizards/install_wizard.py +936 -0
- gitflow_analytics/cli_wizards/run_launcher.py +343 -0
- gitflow_analytics/config/schema.py +12 -0
- gitflow_analytics/constants.py +75 -0
- gitflow_analytics/core/cache.py +7 -3
- gitflow_analytics/core/data_fetcher.py +66 -30
- gitflow_analytics/core/git_timeout_wrapper.py +6 -4
- gitflow_analytics/core/progress.py +2 -4
- gitflow_analytics/core/subprocess_git.py +31 -5
- gitflow_analytics/identity_llm/analysis_pass.py +13 -3
- gitflow_analytics/identity_llm/analyzer.py +14 -2
- gitflow_analytics/identity_llm/models.py +7 -1
- gitflow_analytics/qualitative/classifiers/llm/openai_client.py +5 -3
- gitflow_analytics/security/config.py +6 -6
- gitflow_analytics/security/extractors/dependency_checker.py +14 -14
- gitflow_analytics/security/extractors/secret_detector.py +8 -14
- gitflow_analytics/security/extractors/vulnerability_scanner.py +9 -9
- gitflow_analytics/security/llm_analyzer.py +10 -10
- gitflow_analytics/security/security_analyzer.py +17 -17
- gitflow_analytics/tui/screens/analysis_progress_screen.py +1 -1
- gitflow_analytics/ui/progress_display.py +36 -29
- gitflow_analytics/verify_activity.py +23 -26
- {gitflow_analytics-3.3.0.dist-info → gitflow_analytics-3.4.7.dist-info}/METADATA +1 -1
- {gitflow_analytics-3.3.0.dist-info → gitflow_analytics-3.4.7.dist-info}/RECORD +31 -29
- gitflow_analytics/security/reports/__init__.py +0 -5
- gitflow_analytics/security/reports/security_report.py +0 -358
- {gitflow_analytics-3.3.0.dist-info → gitflow_analytics-3.4.7.dist-info}/WHEEL +0 -0
- {gitflow_analytics-3.3.0.dist-info → gitflow_analytics-3.4.7.dist-info}/entry_points.txt +0 -0
- {gitflow_analytics-3.3.0.dist-info → gitflow_analytics-3.4.7.dist-info}/licenses/LICENSE +0 -0
- {gitflow_analytics-3.3.0.dist-info → gitflow_analytics-3.4.7.dist-info}/top_level.txt +0 -0
gitflow_analytics/_version.py
CHANGED
gitflow_analytics/cli.py
CHANGED
|
@@ -33,6 +33,8 @@ from .reports.weekly_trends_writer import WeeklyTrendsWriter
|
|
|
33
33
|
from .training.pipeline import CommitClassificationTrainer
|
|
34
34
|
from .ui.progress_display import create_progress_display
|
|
35
35
|
|
|
36
|
+
logger = logging.getLogger(__name__)
|
|
37
|
+
|
|
36
38
|
|
|
37
39
|
class RichHelpFormatter:
|
|
38
40
|
"""Rich help formatter for enhanced CLI help display."""
|
|
@@ -48,8 +50,19 @@ class RichHelpFormatter:
|
|
|
48
50
|
return help_text
|
|
49
51
|
|
|
50
52
|
@staticmethod
|
|
51
|
-
def format_option_help(
|
|
52
|
-
|
|
53
|
+
def format_option_help(
|
|
54
|
+
description: str, default: Optional[str] = None, choices: Optional[list[str]] = None
|
|
55
|
+
) -> str:
|
|
56
|
+
"""Format option help with default and choices.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
description: Option description text
|
|
60
|
+
default: Default value to display (optional)
|
|
61
|
+
choices: List of valid choices (optional)
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
Formatted help text string
|
|
65
|
+
"""
|
|
53
66
|
help_text = description
|
|
54
67
|
if default is not None:
|
|
55
68
|
help_text += f" [default: {default}]"
|
|
@@ -281,12 +294,18 @@ class TUIAsDefaultGroup(click.Group):
|
|
|
281
294
|
if args and args[0].startswith("-"):
|
|
282
295
|
# Check if TUI dependencies are available
|
|
283
296
|
try:
|
|
284
|
-
import
|
|
297
|
+
import importlib.util
|
|
285
298
|
|
|
299
|
+
textual_spec = importlib.util.find_spec("textual")
|
|
286
300
|
# TUI is available - route to TUI
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
301
|
+
if textual_spec is not None:
|
|
302
|
+
new_args = ["tui"] + args
|
|
303
|
+
return super().parse_args(ctx, new_args)
|
|
304
|
+
else:
|
|
305
|
+
# TUI not available - fallback to analyze
|
|
306
|
+
new_args = ["analyze"] + args
|
|
307
|
+
return super().parse_args(ctx, new_args)
|
|
308
|
+
except (ImportError, ValueError):
|
|
290
309
|
# TUI not available - fallback to analyze
|
|
291
310
|
new_args = ["analyze"] + args
|
|
292
311
|
return super().parse_args(ctx, new_args)
|
|
@@ -1066,10 +1085,7 @@ def analyze(
|
|
|
1066
1085
|
)
|
|
1067
1086
|
|
|
1068
1087
|
# Extract commits from the raw data
|
|
1069
|
-
if raw_data and raw_data.get("commits")
|
|
1070
|
-
commits = raw_data["commits"]
|
|
1071
|
-
else:
|
|
1072
|
-
commits = []
|
|
1088
|
+
commits = raw_data["commits"] if raw_data and raw_data.get("commits") else []
|
|
1073
1089
|
all_commits.extend(commits)
|
|
1074
1090
|
|
|
1075
1091
|
if not all_commits:
|
|
@@ -4460,6 +4476,114 @@ def merge_identity(config: Path, dev1: str, dev2: str) -> None:
|
|
|
4460
4476
|
sys.exit(1)
|
|
4461
4477
|
|
|
4462
4478
|
|
|
4479
|
+
@cli.command(name="run")
|
|
4480
|
+
@click.option(
|
|
4481
|
+
"--config",
|
|
4482
|
+
"-c",
|
|
4483
|
+
type=click.Path(exists=True, path_type=Path),
|
|
4484
|
+
help="Path to configuration file (optional, will search for default)",
|
|
4485
|
+
)
|
|
4486
|
+
def run_launcher(config: Optional[Path]) -> None:
|
|
4487
|
+
"""Interactive launcher for gitflow-analytics.
|
|
4488
|
+
|
|
4489
|
+
\b
|
|
4490
|
+
This interactive command guides you through:
|
|
4491
|
+
• Repository selection (multi-select)
|
|
4492
|
+
• Analysis period configuration
|
|
4493
|
+
• Cache management
|
|
4494
|
+
• Identity analysis preferences
|
|
4495
|
+
• Preferences storage
|
|
4496
|
+
|
|
4497
|
+
\b
|
|
4498
|
+
EXAMPLES:
|
|
4499
|
+
# Launch interactive mode
|
|
4500
|
+
gitflow-analytics run
|
|
4501
|
+
|
|
4502
|
+
# Launch with specific config
|
|
4503
|
+
gitflow-analytics run -c config.yaml
|
|
4504
|
+
|
|
4505
|
+
\b
|
|
4506
|
+
PREFERENCES:
|
|
4507
|
+
Your selections are saved to the launcher section
|
|
4508
|
+
in your configuration file for future use.
|
|
4509
|
+
|
|
4510
|
+
\b
|
|
4511
|
+
WORKFLOW:
|
|
4512
|
+
1. Select repositories to analyze
|
|
4513
|
+
2. Choose analysis period (weeks)
|
|
4514
|
+
3. Configure cache clearing
|
|
4515
|
+
4. Set identity analysis preference
|
|
4516
|
+
5. Run analysis with your selections
|
|
4517
|
+
"""
|
|
4518
|
+
try:
|
|
4519
|
+
from .cli_wizards.run_launcher import run_interactive_launcher
|
|
4520
|
+
|
|
4521
|
+
success = run_interactive_launcher(config_path=config)
|
|
4522
|
+
sys.exit(0 if success else 1)
|
|
4523
|
+
|
|
4524
|
+
except Exception as e:
|
|
4525
|
+
click.echo(f"❌ Launcher failed: {e}", err=True)
|
|
4526
|
+
logger.error(f"Launcher error: {type(e).__name__}")
|
|
4527
|
+
sys.exit(1)
|
|
4528
|
+
|
|
4529
|
+
|
|
4530
|
+
@cli.command(name="install")
|
|
4531
|
+
@click.option(
|
|
4532
|
+
"--output-dir",
|
|
4533
|
+
type=click.Path(path_type=Path),
|
|
4534
|
+
default=".",
|
|
4535
|
+
help="Directory for config files (default: current directory)",
|
|
4536
|
+
)
|
|
4537
|
+
@click.option(
|
|
4538
|
+
"--skip-validation",
|
|
4539
|
+
is_flag=True,
|
|
4540
|
+
help="Skip credential validation (for testing)",
|
|
4541
|
+
)
|
|
4542
|
+
def install_command(output_dir: Path, skip_validation: bool) -> None:
|
|
4543
|
+
"""Interactive installation wizard for GitFlow Analytics.
|
|
4544
|
+
|
|
4545
|
+
\b
|
|
4546
|
+
This wizard will guide you through setting up GitFlow Analytics:
|
|
4547
|
+
• GitHub credentials and repository configuration
|
|
4548
|
+
• Optional JIRA integration
|
|
4549
|
+
• Optional AI-powered insights (OpenRouter/ChatGPT)
|
|
4550
|
+
• Analysis settings and defaults
|
|
4551
|
+
|
|
4552
|
+
\b
|
|
4553
|
+
EXAMPLES:
|
|
4554
|
+
# Run installation wizard in current directory
|
|
4555
|
+
gitflow-analytics install
|
|
4556
|
+
|
|
4557
|
+
# Install to specific directory
|
|
4558
|
+
gitflow-analytics install --output-dir ./my-config
|
|
4559
|
+
|
|
4560
|
+
\b
|
|
4561
|
+
The wizard will:
|
|
4562
|
+
1. Validate all credentials before saving
|
|
4563
|
+
2. Generate config.yaml and .env files
|
|
4564
|
+
3. Set secure permissions on .env (0600)
|
|
4565
|
+
4. Update .gitignore if in a git repository
|
|
4566
|
+
5. Test the configuration
|
|
4567
|
+
6. Optionally run initial analysis
|
|
4568
|
+
|
|
4569
|
+
\b
|
|
4570
|
+
SECURITY NOTES:
|
|
4571
|
+
• .env file contains sensitive credentials
|
|
4572
|
+
• Never commit .env to version control
|
|
4573
|
+
• File permissions set to owner-only (0600)
|
|
4574
|
+
"""
|
|
4575
|
+
try:
|
|
4576
|
+
from .cli_wizards.install_wizard import InstallWizard
|
|
4577
|
+
|
|
4578
|
+
wizard = InstallWizard(output_dir=Path(output_dir), skip_validation=skip_validation)
|
|
4579
|
+
success = wizard.run()
|
|
4580
|
+
sys.exit(0 if success else 1)
|
|
4581
|
+
|
|
4582
|
+
except Exception as e:
|
|
4583
|
+
click.echo(f"❌ Installation failed: {e}", err=True)
|
|
4584
|
+
sys.exit(1)
|
|
4585
|
+
|
|
4586
|
+
|
|
4463
4587
|
@cli.command(name="discover-storypoint-fields")
|
|
4464
4588
|
@click.option(
|
|
4465
4589
|
"--config",
|
|
@@ -4672,16 +4796,41 @@ def identities(config: Path, weeks: int, apply: bool) -> None:
|
|
|
4672
4796
|
# Show suggestions
|
|
4673
4797
|
click.echo(f"\n⚠️ Found {len(identity_result.clusters)} potential identity clusters:")
|
|
4674
4798
|
|
|
4675
|
-
# Display all mappings
|
|
4799
|
+
# Display all mappings with confidence scores
|
|
4676
4800
|
if suggested_config.get("analysis", {}).get("manual_identity_mappings"):
|
|
4677
4801
|
click.echo("\n📋 Suggested identity mappings:")
|
|
4678
|
-
for mapping in
|
|
4679
|
-
|
|
4802
|
+
for i, mapping in enumerate(
|
|
4803
|
+
suggested_config["analysis"]["manual_identity_mappings"], 1
|
|
4804
|
+
):
|
|
4805
|
+
canonical = mapping["primary_email"]
|
|
4680
4806
|
aliases = mapping.get("aliases", [])
|
|
4807
|
+
confidence = mapping.get("confidence", 0.0)
|
|
4808
|
+
reasoning = mapping.get("reasoning", "")
|
|
4809
|
+
|
|
4810
|
+
# Color-code based on confidence (90%+ threshold)
|
|
4811
|
+
if confidence >= 0.95:
|
|
4812
|
+
confidence_indicator = "🟢" # Very high confidence
|
|
4813
|
+
elif confidence >= 0.90:
|
|
4814
|
+
confidence_indicator = "🟡" # High confidence (above threshold)
|
|
4815
|
+
else:
|
|
4816
|
+
confidence_indicator = "🟠" # Medium confidence (below threshold)
|
|
4817
|
+
|
|
4681
4818
|
if aliases:
|
|
4682
|
-
click.echo(
|
|
4819
|
+
click.echo(
|
|
4820
|
+
f"\n {confidence_indicator} Cluster {i} "
|
|
4821
|
+
f"(Confidence: {confidence:.1%}):"
|
|
4822
|
+
)
|
|
4823
|
+
click.echo(f" Primary: {canonical}")
|
|
4683
4824
|
for alias in aliases:
|
|
4684
|
-
click.echo(f"
|
|
4825
|
+
click.echo(f" Alias: {alias}")
|
|
4826
|
+
|
|
4827
|
+
# Show reasoning if available
|
|
4828
|
+
if reasoning:
|
|
4829
|
+
# Truncate reasoning for display
|
|
4830
|
+
display_reasoning = (
|
|
4831
|
+
reasoning if len(reasoning) <= 80 else reasoning[:77] + "..."
|
|
4832
|
+
)
|
|
4833
|
+
click.echo(f" Reason: {display_reasoning}")
|
|
4685
4834
|
|
|
4686
4835
|
# Check for bot exclusions
|
|
4687
4836
|
if suggested_config.get("exclude", {}).get("authors"):
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""CLI subpackage for GitFlow Analytics.
|
|
2
|
+
|
|
3
|
+
This package contains CLI-related modules including the installation wizard
|
|
4
|
+
and interactive launcher.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .install_wizard import InstallWizard
|
|
8
|
+
from .run_launcher import InteractiveLauncher, run_interactive_launcher
|
|
9
|
+
|
|
10
|
+
__all__ = ["InstallWizard", "InteractiveLauncher", "run_interactive_launcher"]
|