Skip to content

Instantly share code, notes, and snippets.

@redwraith2
Created March 15, 2023 05:10
Show Gist options
  • Save redwraith2/0d2bfd69068df5d2947d020fe08f1966 to your computer and use it in GitHub Desktop.
Save redwraith2/0d2bfd69068df5d2947d020fe08f1966 to your computer and use it in GitHub Desktop.
This script create a text output of the dependency tree of a particular class file. This is useful for coding in ChatGPT because it will allow you to select a class file, a folder, and instantly grab all relevant code from that folder that is referenced either in that class file or a dependency. The script is a simple python script that: 1. take…
import os
import re
import tkinter as tk
from tkinter import filedialog
from datetime import datetime
def get_all_files_with_ext(path, ext):
files_with_ext = []
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith(ext):
files_with_ext.append(os.path.join(root, file))
return files_with_ext
def filter_file(folder, file, last_extension):
with open(file, 'r') as f:
content = f.read()
words = set(re.findall(r'\w+', content))
dependencies = []
for root, dirs, files in os.walk(folder):
for filename in files:
file_basename, file_ext = os.path.splitext(filename)
if file_basename in words and file_ext == last_extension:
dependencies.append(os.path.join(root, filename))
return dependencies
def filter_files(folder, file):
# Get the last file extension
input_file_ext = '.' + file.split('.')[-1]
dependencies = filter_file(folder, file, input_file_ext)
new_dependencies = []
while True:
for dependency in dependencies:
new_dependencies.extend(filter_file(folder, dependency, input_file_ext))
new_dependencies = list(set(new_dependencies))
if set(dependencies) == set(new_dependencies):
break
dependencies = list(set(dependencies).union(set(new_dependencies)))
new_dependencies.clear()
return dependencies
def combine_cs_files(cs_files, output_file, root_path):
with open(output_file, 'w') as outfile:
for file in cs_files:
relative_path = os.path.relpath(file, root_path)
header = f"// File: {relative_path}\n"
outfile.write(header)
with open(file, 'r') as infile:
content = infile.read()
outfile.write(content)
outfile.write('\n\n')
def display_class_list(filtered_files, folder_path, file_path):
def on_submit():
selected_files.extend([file_var.get() for file_var in file_vars if file_var.get()])
window.destroy()
def _on_mousewheel(event):
canvas.yview_scroll(-1 * int(event.delta / 120), "units")
def _on_button4(event):
canvas.yview_scroll(-1, "units")
def _on_button5(event):
canvas.yview_scroll(1, "units")
selected_files = []
window = tk.Toplevel()
window.title("Select Files to Combine")
frame = tk.Frame(window)
frame.pack()
canvas = tk.Canvas(frame)
scrollbar = tk.Scrollbar(frame, orient="vertical", command=canvas.yview)
scrollable_frame = tk.Frame(canvas)
scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
)
canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)
# Bind mouse wheel events for scrolling
canvas.bind_all("<MouseWheel>", _on_mousewheel)
canvas.bind_all("<Button-4>", _on_button4)
canvas.bind_all("<Button-5>", _on_button5)
# Sort filtered_files based on their relative paths
for file in filtered_files:
filtered_files.sort(key=lambda file: (
os.path.relpath(file, folder_path) != os.path.relpath(file_path, folder_path),
folder_distance(file_path, folder_path, file),
'/' in os.path.relpath(file, folder_path) or '\\' in os.path.relpath(file, folder_path),
os.path.relpath(file, folder_path).lower()
))
file_vars = []
for file in filtered_files:
relative_path = os.path.relpath(file, folder_path)
# Check if the relative path contains a slash
if '/' not in relative_path and '\\' not in relative_path:
# Add a slash at the beginning if it doesn't
relative_path = '\\' + relative_path
file_var = tk.StringVar(value=file)
chk = tk.Checkbutton(scrollable_frame, text=relative_path, variable=file_var, onvalue=file, offvalue="")
chk.pack(anchor="w")
file_vars.append(file_var)
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
submit_button = tk.Button(window, text="Submit", command=on_submit)
submit_button.pack()
window.wait_window()
return selected_files
def folder_distance(input_file, base_folder, other_file):
input_folder = os.path.dirname(input_file)
input_folder_relative = os.path.relpath(input_folder, base_folder)
input_folder_parts = input_folder_relative.split(os.path.sep)
other_folder = os.path.dirname(other_file)
other_folder_relative = os.path.relpath(other_folder, base_folder)
other_folder_parts = other_folder_relative.split(os.path.sep)
shared_base_idx = -1
for idx, (input_folder_part, other_folder_part) in enumerate(zip(input_folder_parts, other_folder_parts)):
if input_folder_part != other_folder_part:
break
shared_base_idx = idx
distance = (len(input_folder_parts) - shared_base_idx -1)*1.1 + (len(other_folder_parts) - shared_base_idx - 1)
return distance
def main():
root = tk.Tk()
root.withdraw()
folder_path = filedialog.askdirectory(title="Select Folder with .cs Files")
if not folder_path:
print("No folder selected, exiting.")
return
file_path = filedialog.askopenfilename(title="Select the .cs File to Start Filtering")
if not file_path:
print("No file selected, exiting.")
return
selected_file_ext = os.path.splitext(file_path)[1]
files_with_ext = get_all_files_with_ext(folder_path, selected_file_ext)
filtered_files = filter_files(folder_path, file_path)
if not filtered_files:
print("No .cs files found after filtering, exiting.")
return
user_selected_files = display_class_list(filtered_files, folder_path, file_path)
if not user_selected_files:
print("No files selected, exiting.")
return
script_dir = os.path.dirname(os.path.abspath(__file__))
folder_name = os.path.basename(folder_path)
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
file_name = os.path.basename(file_path)
file_base, _ = os.path.splitext(file_name)
folder_name = os.path.basename(folder_path)
timestamp = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
output_file = os.path.join(script_dir, f'{file_base}_from_{folder_name}_at_{timestamp}_combined_files.txt')
combine_cs_files(user_selected_files, output_file, folder_path)
print(f"Combined .cs files have been saved to: {output_file}")
if __name__ == "__main__":
main()``
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment