kopipasta 0.14.0__py3-none-any.whl → 0.15.0__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.

Potentially problematic release.


This version of kopipasta might be problematic. Click here for more details.

kopipasta/main.py CHANGED
@@ -4,14 +4,15 @@ import io
4
4
  import json
5
5
  import os
6
6
  import argparse
7
- import ast
8
7
  import re
9
- from textwrap import dedent
8
+ from typing import Dict, List, Optional, Tuple
10
9
  import pyperclip
11
10
  import fnmatch
12
11
 
13
12
  import requests
14
13
 
14
+ FileTuple = Tuple[str, bool, Optional[List[str]], str]
15
+
15
16
  def read_gitignore():
16
17
  default_ignore_patterns = [
17
18
  '.git', 'node_modules', 'venv', '.venv', 'dist', '.idea', '__pycache__',
@@ -425,7 +426,7 @@ def print_char_count(count):
425
426
  token_estimate = count // 4
426
427
  print(f"\rCurrent prompt size: {count} characters (~ {token_estimate} tokens)", flush=True)
427
428
 
428
- def select_files_in_directory(directory, ignore_patterns, current_char_count=0):
429
+ def select_files_in_directory(directory: str, ignore_patterns: List[str], current_char_count: int = 0) -> Tuple[List[FileTuple], int]:
429
430
  files = [f for f in os.listdir(directory)
430
431
  if os.path.isfile(os.path.join(directory, f)) and not is_ignored(os.path.join(directory, f), ignore_patterns) and not is_binary(os.path.join(directory, f))]
431
432
 
@@ -445,8 +446,8 @@ def select_files_in_directory(directory, ignore_patterns, current_char_count=0):
445
446
  while True:
446
447
  print_char_count(current_char_count)
447
448
  choice = input("(y)es add all / (n)o ignore all / (s)elect individually / (q)uit? ").lower()
449
+ selected_files: List[FileTuple] = []
448
450
  if choice == 'y':
449
- selected_files = []
450
451
  for file in files:
451
452
  file_path = os.path.join(directory, file)
452
453
  if is_large_file(file_path):
@@ -456,13 +457,13 @@ def select_files_in_directory(directory, ignore_patterns, current_char_count=0):
456
457
  break
457
458
  print("Invalid choice. Please enter 'f' or 's'.")
458
459
  if snippet_choice == 's':
459
- selected_files.append((file, True))
460
+ selected_files.append((file, True, None, get_language_for_file(file)))
460
461
  current_char_count += len(get_file_snippet(file_path))
461
462
  else:
462
- selected_files.append((file, False))
463
+ selected_files.append((file, False, None, get_language_for_file(file)))
463
464
  current_char_count += os.path.getsize(file_path)
464
465
  else:
465
- selected_files.append((file, False))
466
+ selected_files.append((file, False, None, get_language_for_file(file)))
466
467
  current_char_count += os.path.getsize(file_path)
467
468
  print(f"Added all files from {directory}")
468
469
  return selected_files, current_char_count
@@ -470,7 +471,6 @@ def select_files_in_directory(directory, ignore_patterns, current_char_count=0):
470
471
  print(f"Ignored all files from {directory}")
471
472
  return [], current_char_count
472
473
  elif choice == 's':
473
- selected_files = []
474
474
  for file in files:
475
475
  file_path = os.path.join(directory, file)
476
476
  file_size = os.path.getsize(file_path)
@@ -489,13 +489,13 @@ def select_files_in_directory(directory, ignore_patterns, current_char_count=0):
489
489
  break
490
490
  print("Invalid choice. Please enter 'f' or 's'.")
491
491
  if snippet_choice == 's':
492
- selected_files.append((file, True))
492
+ selected_files.append((file, True, None, get_language_for_file(file_path)))
493
493
  current_char_count += len(get_file_snippet(file_path))
494
494
  else:
495
- selected_files.append((file, False))
495
+ selected_files.append((file, False, None, get_language_for_file(file_path)))
496
496
  current_char_count += file_char_estimate
497
497
  else:
498
- selected_files.append((file, False))
498
+ selected_files.append((file, False, None, get_language_for_file(file_path)))
499
499
  current_char_count += file_char_estimate
500
500
  break
501
501
  elif file_choice == 'n':
@@ -503,7 +503,7 @@ def select_files_in_directory(directory, ignore_patterns, current_char_count=0):
503
503
  elif file_choice == 'p':
504
504
  chunks, char_count = select_file_patches(file_path)
505
505
  if chunks:
506
- selected_files.append((file_path, False, chunks))
506
+ selected_files.append((file_path, False, chunks, get_language_for_file(file_path)))
507
507
  current_char_count += char_count
508
508
  break
509
509
  elif file_choice == 'q':
@@ -520,7 +520,7 @@ def select_files_in_directory(directory, ignore_patterns, current_char_count=0):
520
520
  print("Invalid choice. Please try again.")
521
521
 
522
522
  def process_directory(directory, ignore_patterns, current_char_count=0):
523
- files_to_include = []
523
+ files_to_include: List[FileTuple] = []
524
524
  processed_dirs = set()
525
525
 
526
526
  for root, dirs, files in os.walk(directory):
@@ -670,30 +670,29 @@ def handle_env_variables(content, env_vars):
670
670
 
671
671
  return content
672
672
 
673
- def generate_prompt(files_to_include, ignore_patterns, web_contents, env_vars):
673
+ def generate_prompt(files_to_include: List[FileTuple], ignore_patterns: List[str], web_contents: Dict[str, Tuple[str, str]], env_vars: Dict[str, str]) -> str:
674
674
  prompt = "# Project Overview\n\n"
675
675
  prompt += "## Project Structure\n\n"
676
676
  prompt += "```\n"
677
677
  prompt += get_project_structure(ignore_patterns)
678
678
  prompt += "\n```\n\n"
679
679
  prompt += "## File Contents\n\n"
680
- for file_tuple in files_to_include:
681
- if len(file_tuple) == 4:
682
- file, content, is_snippet, content_type = file_tuple
683
- chunks = None
684
- else:
685
- file, content, is_snippet, content_type, chunks = file_tuple
680
+ for file, use_snippet, chunks, content_type in files_to_include:
686
681
  relative_path = get_relative_path(file)
687
- language = get_language_for_file(file) if content_type == 'text' else content_type
682
+ language = content_type if content_type else get_language_for_file(file)
688
683
 
689
684
  if chunks is not None:
690
685
  prompt += f"### {relative_path} (selected patches)\n\n```{language}\n"
691
686
  for chunk in chunks:
692
687
  prompt += f"{chunk}\n"
693
688
  prompt += "```\n\n"
689
+ elif use_snippet:
690
+ file_content = get_file_snippet(file)
691
+ prompt += f"### {relative_path} (snippet)\n\n```{language}\n{file_content}\n```\n\n"
694
692
  else:
695
- content = handle_env_variables(content, env_vars)
696
- prompt += f"### {relative_path}{' (snippet)' if is_snippet else ''}\n\n```{language}\n{content}\n```\n\n"
693
+ file_content = read_file_contents(file)
694
+ file_content = handle_env_variables(file_content, env_vars)
695
+ prompt += f"### {relative_path}\n\n```{language}\n{file_content}\n```\n\n"
697
696
 
698
697
  if web_contents:
699
698
  prompt += "## Web Content\n\n"
@@ -722,7 +721,7 @@ def main():
722
721
  ignore_patterns = read_gitignore()
723
722
  env_vars = read_env_file()
724
723
 
725
- files_to_include = []
724
+ files_to_include:List[FileTuple] = []
726
725
  processed_dirs = set()
727
726
  web_contents = {}
728
727
  current_char_count = 0
@@ -740,7 +739,7 @@ def main():
740
739
  file_choice = input(f"{input_path} (y)es include / (n)o skip / (p)atches / (q)uit? ").lower()
741
740
  if file_choice == 'y':
742
741
  use_snippet = is_large_file(input_path)
743
- files_to_include.append((input_path, use_snippet))
742
+ files_to_include.append((input_path, use_snippet, None, get_language_for_file(input_path)))
744
743
  if use_snippet:
745
744
  current_char_count += len(get_file_snippet(input_path))
746
745
  else:
@@ -752,7 +751,7 @@ def main():
752
751
  elif file_choice == 'p':
753
752
  chunks, char_count = select_file_patches(input_path)
754
753
  if chunks:
755
- files_to_include.append((input_path, False, chunks))
754
+ files_to_include.append((input_path, False, chunks, get_language_for_file(input_path)))
756
755
  current_char_count += char_count
757
756
  break
758
757
  elif file_choice == 'q':
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kopipasta
3
- Version: 0.14.0
3
+ Version: 0.15.0
4
4
  Summary: A CLI tool to generate prompts with project structure and file contents
5
5
  Home-page: https://github.com/mkorpela/kopipasta
6
6
  Author: Mikko Korpela
@@ -0,0 +1,8 @@
1
+ kopipasta/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ kopipasta/main.py,sha256=51k6jZXChwZY_CYVnqCqeY_hoHCAj3flN8qnr0vEVQI,31652
3
+ kopipasta-0.15.0.dist-info/LICENSE,sha256=xw4C9TAU7LFu4r_MwSbky90uzkzNtRwAo3c51IWR8lk,1091
4
+ kopipasta-0.15.0.dist-info/METADATA,sha256=ehTVHvX8IWh7hISa0O3bxJqj4a7gBqX9H0JtU1xU2ys,5646
5
+ kopipasta-0.15.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
6
+ kopipasta-0.15.0.dist-info/entry_points.txt,sha256=but54qDNz1-F8fVvGstq_QID5tHjczP7bO7rWLFkc6Y,50
7
+ kopipasta-0.15.0.dist-info/top_level.txt,sha256=iXohixMuCdw8UjGDUp0ouICLYBDrx207sgZIJ9lxn0o,10
8
+ kopipasta-0.15.0.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- kopipasta/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- kopipasta/main.py,sha256=xoH5I0vAbKbz51trNtqItc-d72s2J2f9b7dIKTTFSCE,31094
3
- kopipasta-0.14.0.dist-info/LICENSE,sha256=xw4C9TAU7LFu4r_MwSbky90uzkzNtRwAo3c51IWR8lk,1091
4
- kopipasta-0.14.0.dist-info/METADATA,sha256=onX0C9YmxAPItIrKTlJfoSggPPKZJNs-M1bGaXIlCTY,5646
5
- kopipasta-0.14.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
6
- kopipasta-0.14.0.dist-info/entry_points.txt,sha256=but54qDNz1-F8fVvGstq_QID5tHjczP7bO7rWLFkc6Y,50
7
- kopipasta-0.14.0.dist-info/top_level.txt,sha256=iXohixMuCdw8UjGDUp0ouICLYBDrx207sgZIJ9lxn0o,10
8
- kopipasta-0.14.0.dist-info/RECORD,,