File size: 1,909 Bytes
2f386cc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import os
from typing import Iterable

import streamlit as st
from git import Repo


def list_code_files_in_repository(
    repo_url: str, extensions: list[str]
) -> Iterable[str]:
    """Clone the GitHub repository and return a list of code files with the specified extensions."""
    local_path = clone_github_repository(repo_url)
    return get_all_files_in_directory(local_path, extensions)


@st.cache_data(show_spinner=False)
def clone_github_repository(repo_url: str) -> str:
    """Clone a GitHub repository and return the local path."""
    local_path = repo_url.split("/")[-1]

    if not os.path.exists(local_path):
        Repo.clone_from(repo_url, local_path)

    return local_path


def get_all_files_in_directory(path: str, extensions: list[str]) -> list[str]:
    """Return a list of all files in a directory with the specified extension."""
    files = []
    for root, _, filenames in os.walk(path):
        for filename in filenames:
            if any(filename.endswith(ext) for ext in extensions):
                files.append(os.path.join(root, filename))
    return files


def create_file_tree(code_files: Iterable[str]) -> list[dict[str, str]]:
    file_tree = []
    code_files = sorted(code_files)
    for file in code_files:
        parts = file.split(os.sep)
        current_level = file_tree
        for i, part in enumerate(parts):
            existing = [
                node for node in current_level if node["label"] == part
            ]
            if existing:
                current_level = existing[0].setdefault("children", [])
            else:
                new_node = {
                    "label": part,
                    "value": os.sep.join(parts[: i + 1]),
                }
                current_level.append(new_node)
                if i != len(parts) - 1:
                    current_level = new_node.setdefault("children", [])
    return file_tree