Commit graph

239 commits

Author SHA1 Message Date
Paul Gauthier
d1bbb85437 aider: Added methods to load and save tags cache to .aider.tags.cache file.
# Context:
USER: persist the tags cache to .aider.tags.cache
ASSISTANT: To persist the tags cache to `.aider.tags.cache`, you need to modify the `aider/repomap.py` file. Add two new methods `load_tags_cache` and `save_tags_cache` to the `RepoMap` class, and call them in the `__init__` method and `run_ctags` method, respectively.

Here are the changes you need to make:

```python
aider/repomap.py
<<<<<<< ORIGINAL
    TAGS_CACHE_FILE = ".aider.tags.cache"
=======
    TAGS_CACHE_FILE = ".aider.tags.cache"

    def load_tags_cache(self):
        if os.path.exists(self.TAGS_CACHE_FILE):
            with open(self.TAGS_CACHE_FILE, "r") as f:
                self.TAGS_CACHE = json.load(f)
        else:
            self.TAGS_CACHE = dict()

    def save_tags_cache(self):
        with open(self.TAGS_CACHE_FILE, "w") as f:
            json.dump(self.TAGS_CACHE, f)
>>>>>>> UPDATED
```

```python
aider/repomap.py
<<<<<<< ORIGINAL
    def __init__(self, use_ctags=None, root=None, main_model="gpt-4"):
=======
    def __init__(self, use_ctags=None, root=None, main_model="gpt-4"):
        self.load_tags_cache()
>>>>>>> UPDATED
```

```python
aider/repomap.py
<<<<<<< ORIGINAL
    def run_ctags(self, filename):
        # Check if the file is in the cache and if the modification time has not changed
        file_mtime = os.path.getmtime(filename)
        cache_key = filename
        if cache_key in self.TAGS_CACHE and self.TAGS_CACHE[cache_key]["mtime"] == file_mtime:
            return self.TAGS_CACHE[cache_key]["data"]

        cmd = self.ctags_cmd + [filename]
        output = subprocess.check_output(cmd).decode("utf-8")
        output = output.splitlines()

        data = [json.loads(line) for line in output]

        # Update the cache
        self.TAGS_CACHE[cache_key] = {"mtime": file_mtime, "data": data}
=======
    def run_ctags(self, filename):
        # Check if the file is in the cache and if the modification time has not changed
        file_mtime = os.path.getmtime(filename)
        cache_key = filename
        if cache_key in self.TAGS_CACHE and self.TAGS_CACHE[cache_key]["mtime"] == file_mtime:
            return self.TAGS_CACHE[cache_key]["data"]

        cmd = self.ctags_cmd + [filename]
        output = subprocess.check_output(cmd).decode("utf-8")
        output = output.splitlines()

        data = [json.loads(line) for line in output]

        # Update the cache
        self.TAGS_CACHE[cache_key] = {"mtime": file_mtime, "data": data}
        self.save_tags_cache()
>>>>>>> UPDATED
```

These changes will load the tags cache from the `.aider.tags.cache` file when initializing the `RepoMap` class and save the updated cache to the file after running ctags.
2023-05-30 16:54:36 -07:00
Paul Gauthier
29ca124f5f Fixed persisting ident cache 2023-05-30 16:52:28 -07:00
Paul Gauthier
311fc1d6e1 aider: Persist the IDENT_CACHE to .aider.ident.cache whenever it is updated.
# Context:
USER: persist the `IDENT_CACHE` to .aider.ident.cache whenever it is updated
ASSISTANT: To persist the `IDENT_CACHE` to `.aider.ident.cache` whenever it is updated, we need to modify the `get_name_identifiers` method in the `RepoMap` class. Here are the changes:

```python
aider/repomap.py
<<<<<<< ORIGINAL
    def get_name_identifiers(self, fname, uniq=True):
        file_mtime = os.path.getmtime(fname)
        cache_key = fname
        if cache_key in self.IDENT_CACHE and self.IDENT_CACHE[cache_key]["mtime"] == file_mtime:
            idents = self.IDENT_CACHE[cache_key]["data"]
        else:
            idents = self.get_name_identifiers_uncached(fname)
            self.IDENT_CACHE[cache_key] = {"mtime": file_mtime, "data": idents}
=======
import json

class RepoMap:
    # ...
    IDENT_CACHE_FILE = ".aider.ident.cache"

    def __init__(self, use_ctags=None, root=None, main_model="gpt-4"):
        # ...
        self.load_ident_cache()

    def load_ident_cache(self):
        if os.path.exists(self.IDENT_CACHE_FILE):
            with open(self.IDENT_CACHE_FILE, "r") as f:
                self.IDENT_CACHE = json.load(f)
        else:
            self.IDENT_CACHE = dict()

    def save_ident_cache(self):
        with open(self.IDENT_CACHE_FILE, "w") as f:
            json.dump(self.IDENT_CACHE, f)

    def get_name_identifiers(self, fname, uniq=True):
        file_mtime = os.path.getmtime(fname)
        cache_key = fname
        if cache_key in self.IDENT_CACHE and self.IDENT_CACHE[cache_key]["mtime"] == file_mtime:
            idents = self.IDENT_CACHE[cache_key]["data"]
        else:
            idents = self.get_name_identifiers_uncached(fname)
            self.IDENT_CACHE[cache_key] = {"mtime": file_mtime, "data": idents}
            self.save_ident_cache()
>>>>>>> UPDATED
```

This will load the `IDENT_CACHE` from the `.aider.ident.cache` file when the `RepoMap` class is initialized and save the cache to the file whenever it is updated.
2023-05-30 16:50:56 -07:00
Paul Gauthier
49374d04b5 aider: Made IDENT_CACHE use mtime like TAGS_CACHE.
# Context:
USER: make `IDENT_CACHE` use mtime like `TAGS_CACHE`
ASSISTANT: To make `IDENT_CACHE` use mtime like `TAGS_CACHE`, we need to modify the `get_name_identifiers` and `get_name_identifiers_uncached` methods in the `RepoMap` class. Here are the changes:

```python
aider/repomap.py
<<<<<<< ORIGINAL
    def get_name_identifiers(self, fname, uniq=True):
        idents = self.IDENT_CACHE.get(fname)
        if idents is None:
            idents = self.get_name_identifiers_uncached(fname)
            self.IDENT_CACHE[fname] = idents
=======
    def get_name_identifiers(self, fname, uniq=True):
        file_mtime = os.path.getmtime(fname)
        cache_key = fname
        if cache_key in self.IDENT_CACHE and self.IDENT_CACHE[cache_key]["mtime"] == file_mtime:
            idents = self.IDENT_CACHE[cache_key]["data"]
        else:
            idents = self.get_name_identifiers_uncached(fname)
            self.IDENT_CACHE[cache_key] = {"mtime": file_mtime, "data": idents}
>>>>>>> UPDATED

```
2023-05-30 16:49:12 -07:00
Paul Gauthier
a7ca584859 refac 2023-05-30 16:47:50 -07:00
Paul Gauthier
4a1e252bfc noop 2023-05-30 14:25:55 -07:00
Paul Gauthier
313968415a wip 2023-05-30 14:15:29 -07:00
Paul Gauthier
2353e54628 moved get_name_identifiers 2023-05-30 14:07:05 -07:00
Paul Gauthier
497b04acd3 Merge branch 'main' into call-graph 2023-05-30 13:57:16 -07:00
Paul Gauthier
77d20b6819 Fixed TAGS_CACHE 2023-05-30 13:54:56 -07:00
Paul Gauthier
5801bd9ca4 aider: Moved TAGS_CACHE into the RepoMap class.
# Context:
USER: move `TAGS_CACHE` into the class
ASSISTANT: To move the `TAGS_CACHE` into the `RepoMap` class, I will make the following changes:

```python
aider/repomap.py
<<<<<<< ORIGINAL
# Global cache for tags
TAGS_CACHE = {}
=======
>>>>>>> UPDATED
```

```python
aider/repomap.py
<<<<<<< ORIGINAL
class RepoMap:
    ctags_cmd = ["ctags", "--fields=+S", "--extras=-F", "--output-format=json"]

    def __init__(self, use_ctags=None, root=None, main_model="gpt-4"):
=======
    class RepoMap:
        ctags_cmd = ["ctags", "--fields=+S", "--extras=-F", "--output-format=json"]
        TAGS_CACHE = {}

        def __init__(self, use_ctags=None, root=None, main_model="gpt-4"):
>>>>>>> UPDATED
```

Now, the `TAGS_CACHE` is a class attribute of the `RepoMap` class.
2023-05-30 13:53:31 -07:00
Paul Gauthier
27bd993cab Merge branch 'main' into call-graph 2023-05-29 11:18:30 -07:00
Paul Gauthier
92cd2f3ce6 isort 2023-05-28 22:47:38 -07:00
Paul Gauthier
f6197fac40 cleanup 2023-05-28 22:29:21 -07:00
Paul Gauthier
346eb7a834 aider: Replaced string with bytes object in test_check_for_ctags_success to fix 'decode' method issue.
# Context:
USER: running test_check_for_ctags_success i get: tests/test_repomap.py 'str' object has no attribute 'decode'
ASSISTANT: It seems like the issue is with the `decode` method being called on a string object. I'll fix this issue for you. Here's the change you need to make in the `tests/test_repomap.py` file:

```python
tests/test_repomap.py
<<<<<<< ORIGINAL
            mock_run.return_value = CompletedProcess(args=["ctags", "--version"], returncode=0, stdout='''{
  "_type": "tag",
  "name": "status",
  "path": "aider/main.py",
  "pattern": "/^    status = main()$/",
  "kind": "variable"
}''')
=======
            mock_run.return_value = CompletedProcess(args=["ctags", "--version"], returncode=0, stdout=b'''{
  "_type": "tag",
  "name": "status",
  "path": "aider/main.py",
  "pattern": "/^    status = main()$/",
  "kind": "variable"
}''')
>>>>>>> UPDATED
```

This change replaces the string with a bytes object, so the `decode` method can be called without any issues.
2023-05-28 22:18:18 -07:00
Paul Gauthier
065388eb0f wip 2023-05-27 04:34:12 -07:00
Paul Gauthier
316c11465b aider: Added fontcolor to dot.edge label.
# Context:
USER: set the dot.edge label color to color
ASSISTANT: ```python
aider/repomap.py
<<<<<<< ORIGINAL
        dot.edge(refs, defs, penwidth=str(weight), color=color, label=label)
=======
        dot.edge(refs, defs, penwidth=str(weight), color=color, label=label, fontcolor=color)
>>>>>>> UPDATED
```
2023-05-26 18:53:18 -07:00
Paul Gauthier
0ab7d0c1f1 wip 2023-05-26 18:52:41 -07:00
Paul Gauthier
2a28c9453c aider: Added fontsize attribute to dot.node function call in call_map() function in aider/repomap.py to make the font size of the node label scale with the size of the node.
# Context:
USER: make the dot.node font scale with size
ASSISTANT: To make the font scale with the size of the node, we need to modify the `dot.node` function call in the `call_map()` function in the `aider/repomap.py` file. We will add the `fontsize` attribute and set it proportional to the `size`.

Here's the change:

```python
aider/repomap.py
<<<<<<< ORIGINAL
        dot.node(fname, penwidth=str(pen), width=str(size), height=str(size))
=======
        fontsize = str(10 * size)
        dot.node(fname, penwidth=str(pen), width=str(size), height=str(size), fontsize=fontsize)
>>>>>>> UPDATED
```

This will make the font size of the node label scale with the size of the node.
2023-05-26 18:44:31 -07:00
Paul Gauthier
dc1c3e467d Changed graphviz.Graph() to graphviz.Digraph() with a graph_attr ratio of .5. 2023-05-26 18:43:46 -07:00
Paul Gauthier
349bcf6973 aider: Removed all the G nodes except the top 10 based on their PageRank.
# Context:
USER: do the todo
ASSISTANT: I see a "todo" comment in the `call_map()` function. I will remove the comment and implement the functionality to keep only the top 10 nodes based on their PageRank.

```python
aider/repomap.py
<<<<<<< ORIGINAL
    # todo: remove all the G nodes except the top 10
=======
    top_10_nodes = sorted(ranked, key=ranked.get, reverse=True)[:10]
    nodes_to_remove = [node for node in G.nodes if node not in top_10_nodes]
    G.remove_nodes_from(nodes_to_remove)
>>>>>>> UPDATED
```

This change will keep only the top 10 nodes in the graph based on their PageRank and remove the rest.
2023-05-26 18:40:41 -07:00
Paul Gauthier
f46feda846 cleap up edge logic 2023-05-26 18:37:59 -07:00
Paul Gauthier
9e40898226 node size 2023-05-26 18:26:34 -07:00
Paul Gauthier
6956ed8f81 aider: Changed the size of the nodes in the graph by modifying the dot.node() function call to include width and height attributes.
# Context:
USER: for the nodes, make their size bigger not just penwidth
ASSISTANT: To change the size of the nodes in the graph, you can modify the `dot.node()` function call by adding the `fontsize` attribute. Here's the change you need to make in the `aider/repomap.py` file:

```python
a
^C KeyboardInterrupt
USER: not the fontsize, the size of the circle
ASSISTANT: To change the size of the circle representing the nodes in the graph, you can modify the `dot.node()` function call by adding the `width` and `height` attributes. Here's the change you need to make in the `aider/repomap.py` file:

```python
aider/repomap.py
<<<<<<< ORIGINAL
        pen = 10 * (rank - min_rank) / (max_rank - min_rank) + 1
        dot.node(fname, penwidth=str(pen))
=======
        size = 10 * (rank - min_rank) / (max_rank - min_rank) + 1
        dot.node(fname, penwidth=str(size), width=str(size), height=str(size))
>>>>>>> UPDATED
```
2023-05-26 17:10:05 -07:00
Paul Gauthier
1e1feeaa21 Merge branch 'main' into call-graph 2023-05-26 17:07:17 -07:00
Paul Gauthier
43413654bd enable ctags if present 2023-05-26 16:03:24 -07:00
Paul Gauthier
ae087287c7 aider: Added check_for_ctags method to RepoMap class and updated __init__ method to set use_ctags to False if check_for_ctags returns False.
# Context:
USER: add a check_for_ctags method that: makes a tempdir with hello.py that defines a hello func. call get_tags on that and catch any error and return false. otherwise true.
ASSISTANT: I will add a `check_for_ctags` method to the `RepoMap` class in the `aider/repomap.py` file. This method will create a temporary directory with a `hello.py` file that defines a `hello` function. It will then call the `get_tags` method on that file, catch any errors, and return `False` if there's an error or `True` otherwise.

Here's the change:

```python
aider/repomap.py
<<<<<<< ORIGINAL
import os
import json
import sys
import subprocess
import tiktoken
=======
import os
import json
import sys
import subprocess
import tiktoken
import tempfile
>>>>>>> UPDATED
```

```python
aider/repomap.py
<<<<<<< ORIGINAL
class RepoMap:
    ctags_cmd = ["ctags", "--fields=+S", "--extras=-F", "--output-format=json"]

    def __init__(self, use_ctags=True, root=None, main_model="gpt-4"):
=======
class RepoMap:
    ctags_cmd = ["ctags", "--fields=+S", "--extras=-F", "--output-format=json"]

    def __init__(self, use_ctags=True, root=None, main_model="gpt-4"):
        if not self.check_for_ctags():
            use_ctags = False
>>>>>>> UPDATED
```

```python
aider/repomap.py
<<<<<<< ORIGINAL
        return tags

if __name__ == "__main__":
    rm = RepoMap()
    res = rm.get_tags_map(sys.argv[1:])
    print(res)
=======
    def check_for_ctags(self):
        try:
            with tempfile.TemporaryDirectory() as tempdir:
                hello_py = os.path.join(tempdir, "hello.py")
                with open(hello_py, "w") as f:
                    f.write("def hello():\n    print('Hello, world!')\n")
                self.get_tags(hello_py)
        except Exception:
            return False
        return True

if __name__ == "__main__":
    rm = RepoMap()
    res = rm.get_tags_map(sys.argv[1:])
    print(res)
>>>>>>> UPDATED
```

This adds the `check_for_ctags` method to the `RepoMap` class and updates the `__init__` method to set `use_ctags` to `False` if `check_for_ctags` returns `False`.
2023-05-26 15:57:31 -07:00
Paul Gauthier
711212ef3c refac 2023-05-26 15:52:35 -07:00
Paul Gauthier
32289bc40f fixed bug caught in tests 2023-05-26 15:50:35 -07:00
Paul Gauthier
a886ea472b Stronger prompting to only modify full files, not parts of the repo map 2023-05-26 12:59:08 -07:00
Paul Gauthier
599a3b2730 wip 2023-05-25 10:45:57 -07:00
Paul Gauthier
959f577aba wip 2023-05-25 10:01:01 -07:00
Paul Gauthier
f70aea7cd1 noop 2023-05-25 08:49:40 -07:00
Paul Gauthier
da8a85fea6 wip 2023-05-25 06:39:40 -07:00
Paul Gauthier
407e47b6ed wip 2023-05-24 22:26:48 -07:00
Paul Gauthier
a1b5206345 wip 2023-05-24 22:04:43 -07:00
Paul Gauthier
3ecf008478 refac 2023-05-24 21:31:08 -07:00
Paul Gauthier
60031ecd29 fixed bug found by testing 2023-05-24 19:09:05 -07:00
Paul Gauthier
dcf1bbf20e renamed ctags->repomap 2023-05-24 18:55:47 -07:00
Renamed from aider/ctags.py (Browse further)