gitflow-analytics 3.5.2__py3-none-any.whl → 3.6.1__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.5.2"
3
+ __version__ = "3.6.1"
4
4
  __version_info__ = tuple(int(x) for x in __version__.split("."))
gitflow_analytics/cli.py CHANGED
@@ -4493,11 +4493,123 @@ def merge_identity(config: Path, dev1: str, dev2: str) -> None:
4493
4493
  sys.exit(1)
4494
4494
 
4495
4495
 
4496
+ def _resolve_config_path(config: Optional[Path]) -> Optional[Path]:
4497
+ """Resolve configuration file path, offering to create if missing.
4498
+
4499
+ Args:
4500
+ config: User-specified config path or None
4501
+
4502
+ Returns:
4503
+ Validated config path or None if user cancels
4504
+ """
4505
+ # Default config locations to search
4506
+ default_locations = [
4507
+ Path.cwd() / "config.yaml",
4508
+ Path.cwd() / ".gitflow-analytics.yaml",
4509
+ Path.home() / ".gitflow-analytics" / "config.yaml",
4510
+ ]
4511
+
4512
+ # Case 1: Config specified but doesn't exist
4513
+ if config:
4514
+ config_path = Path(config).resolve()
4515
+ if not config_path.exists():
4516
+ click.echo(f"❌ Configuration file not found: {config_path}\n", err=True)
4517
+
4518
+ if click.confirm("Would you like to create a new configuration?", default=True):
4519
+ click.echo("\n🚀 Launching installation wizard...\n")
4520
+
4521
+ from .cli_wizards.install_wizard import InstallWizard
4522
+
4523
+ wizard = InstallWizard(output_dir=config_path.parent, skip_validation=False)
4524
+
4525
+ # Store the desired config filename for the wizard
4526
+ wizard.config_filename = config_path.name
4527
+
4528
+ success = wizard.run()
4529
+
4530
+ if not success:
4531
+ click.echo("\n❌ Installation wizard cancelled or failed.", err=True)
4532
+ return None
4533
+
4534
+ click.echo(f"\n✅ Configuration created: {config_path}")
4535
+ click.echo("\n🎉 Ready to run analysis!\n")
4536
+ return config_path
4537
+ else:
4538
+ click.echo("\n💡 Create a configuration file with:")
4539
+ click.echo(" gitflow-analytics install")
4540
+ click.echo(f"\nOr manually create: {config_path}\n")
4541
+ return None
4542
+
4543
+ return config_path
4544
+
4545
+ # Case 2: No config specified, search for defaults
4546
+ click.echo("🔍 Looking for configuration files...\n")
4547
+
4548
+ for location in default_locations:
4549
+ if location.exists():
4550
+ click.echo(f"📋 Found configuration: {location}\n")
4551
+ return location
4552
+
4553
+ # No config found anywhere
4554
+ click.echo("No configuration file found. Let's create one!\n")
4555
+
4556
+ # Offer to create config
4557
+ locations = [
4558
+ ("./config.yaml", "Current directory"),
4559
+ (str(Path.home() / ".gitflow-analytics" / "config.yaml"), "User directory"),
4560
+ ]
4561
+
4562
+ click.echo("Where would you like to save the configuration?")
4563
+ for i, (path, desc) in enumerate(locations, 1):
4564
+ click.echo(f" {i}. {path} ({desc})")
4565
+ click.echo(" 3. Custom path")
4566
+
4567
+ try:
4568
+ choice = click.prompt("\nSelect option", type=click.Choice(["1", "2", "3"]), default="1")
4569
+ except (click.exceptions.Abort, EOFError):
4570
+ click.echo("\n⚠️ Cancelled by user.")
4571
+ return None
4572
+
4573
+ if choice == "1":
4574
+ config_path = Path.cwd() / "config.yaml"
4575
+ elif choice == "2":
4576
+ config_path = Path.home() / ".gitflow-analytics" / "config.yaml"
4577
+ else:
4578
+ try:
4579
+ custom_path = click.prompt("Enter configuration file path")
4580
+ config_path = Path(custom_path).expanduser().resolve()
4581
+ except (click.exceptions.Abort, EOFError):
4582
+ click.echo("\n⚠️ Cancelled by user.")
4583
+ return None
4584
+
4585
+ # Launch install wizard
4586
+ click.echo(f"\n🚀 Creating configuration at: {config_path}")
4587
+ click.echo("Launching installation wizard...\n")
4588
+
4589
+ from .cli_wizards.install_wizard import InstallWizard
4590
+
4591
+ wizard = InstallWizard(output_dir=config_path.parent, skip_validation=False)
4592
+
4593
+ # Store the desired config filename for the wizard
4594
+ wizard.config_filename = config_path.name
4595
+
4596
+ success = wizard.run()
4597
+
4598
+ if not success:
4599
+ click.echo("\n❌ Installation wizard cancelled or failed.", err=True)
4600
+ return None
4601
+
4602
+ click.echo(f"\n✅ Configuration created: {config_path}")
4603
+ click.echo("\n🎉 Ready to run analysis!\n")
4604
+
4605
+ return config_path
4606
+
4607
+
4496
4608
  @cli.command(name="run")
4497
4609
  @click.option(
4498
4610
  "--config",
4499
4611
  "-c",
4500
- type=click.Path(exists=True, path_type=Path),
4612
+ type=click.Path(path_type=Path), # Remove exists=True to allow missing files
4501
4613
  help="Path to configuration file (optional, will search for default)",
4502
4614
  )
4503
4615
  def run_launcher(config: Optional[Path]) -> None:
@@ -4533,11 +4645,21 @@ def run_launcher(config: Optional[Path]) -> None:
4533
4645
  5. Run analysis with your selections
4534
4646
  """
4535
4647
  try:
4648
+ # Handle missing config file gracefully
4649
+ config_path = _resolve_config_path(config)
4650
+
4651
+ if not config_path:
4652
+ # No config found or user cancelled
4653
+ sys.exit(1)
4654
+
4536
4655
  from .cli_wizards.run_launcher import run_interactive_launcher
4537
4656
 
4538
- success = run_interactive_launcher(config_path=config)
4657
+ success = run_interactive_launcher(config_path=config_path)
4539
4658
  sys.exit(0 if success else 1)
4540
4659
 
4660
+ except (KeyboardInterrupt, click.exceptions.Abort):
4661
+ click.echo("\n\n⚠️ Launcher cancelled by user.")
4662
+ sys.exit(130)
4541
4663
  except Exception as e:
4542
4664
  click.echo(f"❌ Launcher failed: {e}", err=True)
4543
4665
  logger.error(f"Launcher error: {type(e).__name__}")
@@ -90,6 +90,7 @@ class InstallWizard:
90
90
  self.config_data = {}
91
91
  self.env_data = {}
92
92
  self.profile = None # Selected installation profile
93
+ self.config_filename = "config.yaml" # Default config filename (can be overridden)
93
94
 
94
95
  # Ensure output directory exists
95
96
  self.output_dir.mkdir(parents=True, exist_ok=True)
@@ -968,8 +969,8 @@ class InstallWizard:
968
969
  click.echo("-" * 50)
969
970
 
970
971
  try:
971
- # Generate config.yaml
972
- config_path = self.output_dir / "config.yaml"
972
+ # Generate config file with custom filename
973
+ config_path = self.output_dir / self.config_filename
973
974
  if config_path.exists() and not click.confirm(
974
975
  f"⚠️ {config_path} already exists. Overwrite?", default=False
975
976
  ):
@@ -1084,7 +1085,7 @@ class InstallWizard:
1084
1085
  click.echo("\n📋 Step 7: Validating Installation")
1085
1086
  click.echo("-" * 50)
1086
1087
 
1087
- config_path = self.output_dir / "config.yaml"
1088
+ config_path = self.output_dir / self.config_filename
1088
1089
 
1089
1090
  if not config_path.exists():
1090
1091
  click.echo("❌ Configuration file not found")
@@ -1155,7 +1156,7 @@ class InstallWizard:
1155
1156
  click.echo("✅ Installation Complete!")
1156
1157
  click.echo("=" * 50)
1157
1158
 
1158
- config_path = self.output_dir / "config.yaml"
1159
+ config_path = self.output_dir / self.config_filename
1159
1160
  env_path = self.output_dir / ".env"
1160
1161
 
1161
1162
  click.echo("\n📁 Generated Files:")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitflow-analytics
3
- Version: 3.5.2
3
+ Version: 3.6.1
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=yN1dyAUu4l9qX-YNAGRItEf4RFFe-5GQiOntXPIfdxo,683
2
- gitflow_analytics/_version.py,sha256=VlHh9eAQ34bIRsu31l61B7n-gUeASgbwjJXQ9Hp_IbQ,137
3
- gitflow_analytics/cli.py,sha256=gKfN-fbEPQqEQVgE693xU5yKSlR4TeVXjoI-vG5oIPA,258433
2
+ gitflow_analytics/_version.py,sha256=gkE2IQ8OA_DdXSN7E1TswrWgDyJKqg5sTQJ2bF_27as,137
3
+ gitflow_analytics/cli.py,sha256=Ky_jCZUHOxikbkqWzeKPtjPpPcPV9KFmhaDP5gBc0s0,262769
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
@@ -11,7 +11,7 @@ gitflow_analytics/classification/feature_extractor.py,sha256=W82vztPQO8-MFw9Yt17
11
11
  gitflow_analytics/classification/linguist_analyzer.py,sha256=HjLx9mM7hGXtrvMba6osovHJLAacTx9oDmN6CS5w0bE,17687
12
12
  gitflow_analytics/classification/model.py,sha256=2KbmFh9MpyvHMcNHbqwUTAAVLHHu3MiTfFIPyZSGa-8,16356
13
13
  gitflow_analytics/cli_wizards/__init__.py,sha256=D73D97cS1hZsB_fCQQaAiWtd_w2Lb8TtcGc9Pn2DIyE,343
14
- gitflow_analytics/cli_wizards/install_wizard.py,sha256=aQepE3ThhBPyOjkDj-_p0fKZ2OEVTlq7d_6HEt4JrkQ,44871
14
+ gitflow_analytics/cli_wizards/install_wizard.py,sha256=x5GaYqAgnFwLYyuHnjbuRHL-yw4Mxfi3OzJcQJszeM4,45005
15
15
  gitflow_analytics/cli_wizards/run_launcher.py,sha256=J6G_C7IqxPg7_GhAfbV99D1dIIWwb1s_qmHC7Iv2iGI,15038
16
16
  gitflow_analytics/config/__init__.py,sha256=KziRIbBJctB5LOLcKLzELWA1rXwjS6-C2_DeM_hT9rM,1133
17
17
  gitflow_analytics/config/aliases.py,sha256=z9F0X6qbbF544Tw7sHlOoBj5mpRSddMkCpoKLzvVzDU,10960
@@ -133,9 +133,9 @@ gitflow_analytics/tui/widgets/export_modal.py,sha256=L-XKPOc6u-fow2TudPgDnC0kXZM
133
133
  gitflow_analytics/tui/widgets/progress_widget.py,sha256=Qny6Q1nU0Pr3aj4aHfXLaRjya9MH3rldR2HWYiaQyGE,6167
134
134
  gitflow_analytics/ui/__init__.py,sha256=UBhYhZMvwlSrCuGWjkIdoP2zNbiQxOHOli-I8mqIZUE,441
135
135
  gitflow_analytics/ui/progress_display.py,sha256=3xJnCOSs1DRVAfS-rTu37EsLfWDFW5-mbv-bPS9NMm4,59182
136
- gitflow_analytics-3.5.2.dist-info/licenses/LICENSE,sha256=xwvSwY1GYXpRpmbnFvvnbmMwpobnrdN9T821sGvjOY0,1066
137
- gitflow_analytics-3.5.2.dist-info/METADATA,sha256=7TWOkZxt3KP7_w30_hufQiB8JKsNC6ZGJcPHwNRyMAc,34122
138
- gitflow_analytics-3.5.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
139
- gitflow_analytics-3.5.2.dist-info/entry_points.txt,sha256=a3y8HnfLOvK1QVOgAkDY6VQXXm3o9ZSQRZrpiaS3hEM,65
140
- gitflow_analytics-3.5.2.dist-info/top_level.txt,sha256=CQyxZXjKvpSB1kgqqtuE0PCRqfRsXZJL8JrYpJKtkrk,18
141
- gitflow_analytics-3.5.2.dist-info/RECORD,,
136
+ gitflow_analytics-3.6.1.dist-info/licenses/LICENSE,sha256=xwvSwY1GYXpRpmbnFvvnbmMwpobnrdN9T821sGvjOY0,1066
137
+ gitflow_analytics-3.6.1.dist-info/METADATA,sha256=dxz3wCV2RIKYtgxDXSjmNQk0PCWG8JrpOasAlsOmw-s,34122
138
+ gitflow_analytics-3.6.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
139
+ gitflow_analytics-3.6.1.dist-info/entry_points.txt,sha256=a3y8HnfLOvK1QVOgAkDY6VQXXm3o9ZSQRZrpiaS3hEM,65
140
+ gitflow_analytics-3.6.1.dist-info/top_level.txt,sha256=CQyxZXjKvpSB1kgqqtuE0PCRqfRsXZJL8JrYpJKtkrk,18
141
+ gitflow_analytics-3.6.1.dist-info/RECORD,,