devDocs 2.0.6__tar.gz → 3.0.0__tar.gz
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.
- {devdocs-2.0.6 → devdocs-3.0.0}/PKG-INFO +4 -14
- {devdocs-2.0.6 → devdocs-3.0.0}/README.md +164 -170
- devdocs-3.0.0/devDocs/cli.py +377 -0
- {devdocs-2.0.6 → devdocs-3.0.0}/devDocs.egg-info/PKG-INFO +4 -14
- devdocs-3.0.0/devDocs.egg-info/entry_points.txt +2 -0
- {devdocs-2.0.6 → devdocs-3.0.0}/pyproject.toml +55 -56
- devdocs-3.0.0/setup.py +3 -0
- devdocs-2.0.6/devDocs/cli.py +0 -119
- devdocs-2.0.6/devDocs.egg-info/entry_points.txt +0 -2
- devdocs-2.0.6/setup.py +0 -2
- {devdocs-2.0.6 → devdocs-3.0.0}/devDocs/__init__.py +0 -0
- {devdocs-2.0.6 → devdocs-3.0.0}/devDocs.egg-info/SOURCES.txt +0 -0
- {devdocs-2.0.6 → devdocs-3.0.0}/devDocs.egg-info/dependency_links.txt +0 -0
- {devdocs-2.0.6 → devdocs-3.0.0}/devDocs.egg-info/requires.txt +0 -0
- {devdocs-2.0.6 → devdocs-3.0.0}/devDocs.egg-info/top_level.txt +0 -0
- {devdocs-2.0.6 → devdocs-3.0.0}/setup.cfg +0 -0
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devDocs
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.0
|
|
4
4
|
Summary: AI-powered CLI tool that builds professional '*.md' documentation files of a project for internal teams using the Google Gemini API.
|
|
5
|
-
Author: Gantavya Bansal
|
|
6
5
|
Author-email: Gantavya Bansal <gantavyaoo@gmail.com>
|
|
7
|
-
License: MIT
|
|
6
|
+
License-Expression: MIT
|
|
8
7
|
Project-URL: Homepage, https://github.com/bgantavya/devDocs
|
|
9
8
|
Project-URL: Repository, https://github.com/bgantavya/devDocs
|
|
10
9
|
Project-URL: Issues, https://github.com/bgantavya/devDocs/issues
|
|
@@ -17,7 +16,6 @@ Classifier: Intended Audience :: Information Technology
|
|
|
17
16
|
Classifier: Topic :: Documentation
|
|
18
17
|
Classifier: Topic :: Software Development :: Code Generators
|
|
19
18
|
Classifier: Topic :: Software Development :: Documentation
|
|
20
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
21
19
|
Classifier: Programming Language :: Python :: 3
|
|
22
20
|
Classifier: Programming Language :: Python :: 3.8
|
|
23
21
|
Classifier: Programming Language :: Python :: 3.9
|
|
@@ -28,8 +26,6 @@ Requires-Python: >=3.8
|
|
|
28
26
|
Description-Content-Type: text/markdown
|
|
29
27
|
Requires-Dist: google-genai
|
|
30
28
|
Requires-Dist: httpx
|
|
31
|
-
Dynamic: author
|
|
32
|
-
Dynamic: requires-python
|
|
33
29
|
|
|
34
30
|
|
|
35
31
|
---
|
|
@@ -53,15 +49,14 @@ Before and after running `devDocs`:
|
|
|
53
49
|
```bash
|
|
54
50
|
your-project/
|
|
55
51
|
├── src/
|
|
56
|
-
│ ├──
|
|
57
|
-
│ └──
|
|
52
|
+
│ ├── code
|
|
53
|
+
│ └── s/es
|
|
58
54
|
├── tests/
|
|
59
55
|
├── requirements.txt
|
|
60
56
|
├── LICENSE
|
|
61
57
|
├── docs/ # ← Generated by devDocs
|
|
62
58
|
└── README.md # ← Overwritten by devDocs (if chosen)
|
|
63
59
|
```
|
|
64
|
-
|
|
65
60
|
---
|
|
66
61
|
|
|
67
62
|
## ⚙️ How It Works
|
|
@@ -71,11 +66,6 @@ your-project/
|
|
|
71
66
|
3. **Generates** documentation via Google Gemini
|
|
72
67
|
4. **Saves** output in Markdown format
|
|
73
68
|
|
|
74
|
-
### Optional Features
|
|
75
|
-
|
|
76
|
-
* Preserve existing README (unless `--overwrite` is set)
|
|
77
|
-
* Include/exclude specific files or folders via filters
|
|
78
|
-
|
|
79
69
|
---
|
|
80
70
|
|
|
81
71
|
## 📦 Installation
|
|
@@ -1,171 +1,165 @@
|
|
|
1
|
-
|
|
2
|
-
---
|
|
3
|
-
|
|
4
|
-
# 📘 `devDocs` – AI-Powered README Generator
|
|
5
|
-
|
|
6
|
-
`devDocs` is a command-line tool that automatically generates clean, professional `README.md` files by analyzing your **project structure**, **source code**, and any **existing documentation**.
|
|
7
|
-
|
|
8
|
-
Powered by the **Google Gemini API**, it's ideal for:
|
|
9
|
-
|
|
10
|
-
* 💡 Open-source contributors
|
|
11
|
-
* 🛠️ Internal dev tools
|
|
12
|
-
* 🚀 Hackathon projects needing docs fast
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## 📂 Example Project Layout
|
|
17
|
-
|
|
18
|
-
Before and after running `devDocs`:
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
your-project/
|
|
22
|
-
├── src/
|
|
23
|
-
│ ├──
|
|
24
|
-
│ └──
|
|
25
|
-
├── tests/
|
|
26
|
-
├── requirements.txt
|
|
27
|
-
├── LICENSE
|
|
28
|
-
├── docs/ # ← Generated by devDocs
|
|
29
|
-
└── README.md # ← Overwritten by devDocs (if chosen)
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
|
78
|
-
|
|
|
79
|
-
| `--
|
|
80
|
-
| `--
|
|
81
|
-
| `--
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
###
|
|
127
|
-
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
##
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
## 🤝 Contribute
|
|
167
|
-
|
|
168
|
-
Found a bug or have an idea?
|
|
169
|
-
Open an issue or submit a PR — contributions are always welcome!
|
|
170
|
-
|
|
1
|
+
|
|
2
|
+
---
|
|
3
|
+
|
|
4
|
+
# 📘 `devDocs` – AI-Powered README Generator
|
|
5
|
+
|
|
6
|
+
`devDocs` is a command-line tool that automatically generates clean, professional `README.md` files by analyzing your **project structure**, **source code**, and any **existing documentation**.
|
|
7
|
+
|
|
8
|
+
Powered by the **Google Gemini API**, it's ideal for:
|
|
9
|
+
|
|
10
|
+
* 💡 Open-source contributors
|
|
11
|
+
* 🛠️ Internal dev tools
|
|
12
|
+
* 🚀 Hackathon projects needing docs fast
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 📂 Example Project Layout
|
|
17
|
+
|
|
18
|
+
Before and after running `devDocs`:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
your-project/
|
|
22
|
+
├── src/
|
|
23
|
+
│ ├── code
|
|
24
|
+
│ └── s/es
|
|
25
|
+
├── tests/
|
|
26
|
+
├── requirements.txt
|
|
27
|
+
├── LICENSE
|
|
28
|
+
├── docs/ # ← Generated by devDocs
|
|
29
|
+
└── README.md # ← Overwritten by devDocs (if chosen)
|
|
30
|
+
```
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## ⚙️ How It Works
|
|
34
|
+
|
|
35
|
+
1. **Scans** project directory and source files
|
|
36
|
+
2. **Parses** content (code, comments, old README)
|
|
37
|
+
3. **Generates** documentation via Google Gemini
|
|
38
|
+
4. **Saves** output in Markdown format
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 📦 Installation
|
|
43
|
+
|
|
44
|
+
Install via pip:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install devDocs
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 🔑 Requirements
|
|
53
|
+
|
|
54
|
+
* Python 3.8+
|
|
55
|
+
* Google Gemini API Key (get one at [Google AI Studio](https://aistudio.google.com/))
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 🚀 Usage
|
|
60
|
+
|
|
61
|
+
Run inside your project’s root:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
devDocs [OPTIONS]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Paste your **Gemini API key** when prompted.
|
|
68
|
+
|
|
69
|
+
### CLI Options
|
|
70
|
+
|
|
71
|
+
| Option | Description |
|
|
72
|
+
| --------------- | ------------------------------------------------- |
|
|
73
|
+
| `--path` | Root folder to scan (default: `.`) |
|
|
74
|
+
| `--name` | Project name to display in the README |
|
|
75
|
+
| `--description` | Short project summary |
|
|
76
|
+
| `--authors` | Comma-separated list of authors |
|
|
77
|
+
| `--keywords` | Comma-separated keywords (e.g., cli, docs, ai) |
|
|
78
|
+
| `--overwrite` | Overwrite existing `README.md` (default: False) |
|
|
79
|
+
| `--output` | Output folder (default: `docs/`) |
|
|
80
|
+
| `--exclude` | Comma-separated paths/extensions to exclude |
|
|
81
|
+
| `--include` | Comma-separated paths/extensions to force include |
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### ✅ Example
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
devDocs --path . \
|
|
89
|
+
--name "Cool Dev Tool" \
|
|
90
|
+
--description "Generate AI-based READMEs effortlessly" \
|
|
91
|
+
--authors "Gantavya Bansal" \
|
|
92
|
+
--keywords "cli, docs, automation" \
|
|
93
|
+
--output docs \
|
|
94
|
+
--overwrite
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 🧠 Key Features
|
|
100
|
+
|
|
101
|
+
✅ Auto-generates structured `README.md`
|
|
102
|
+
✅ Respects original files unless `--overwrite`
|
|
103
|
+
✅ Fine-grained include/exclude control
|
|
104
|
+
✅ Generates a visual folder tree
|
|
105
|
+
✅ Clean output in a dedicated `--output` folder
|
|
106
|
+
✅ Backed by Google Gemini for high-quality results
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 🧱 Tech Stack
|
|
111
|
+
|
|
112
|
+
* Python 3.8+
|
|
113
|
+
* [`google-genai`](https://pypi.org/project/google-generativeai/)
|
|
114
|
+
* Built-in: `argparse`, `os`, `logging`, `time`
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 🛠️ Dev Notes
|
|
119
|
+
|
|
120
|
+
### Workflow
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
CLI args → Filter files → Extract context → Call Gemini → Write docs
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### API Prompt Template
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
system_instruction = '''
|
|
130
|
+
You are Gantavya Bansal, a senior engineer and technical writer.
|
|
131
|
+
Generate professional Markdown documentation using context from code and folder structure.
|
|
132
|
+
Include:
|
|
133
|
+
- Title
|
|
134
|
+
- Folder Tree
|
|
135
|
+
- Description
|
|
136
|
+
- Usage
|
|
137
|
+
- Tech Stack
|
|
138
|
+
- Known Issues
|
|
139
|
+
- Licensing
|
|
140
|
+
'''
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## ⚠️ Limitations
|
|
146
|
+
|
|
147
|
+
* 📶 Requires internet (for Gemini API)
|
|
148
|
+
* 🔁 Retry logic for failed API calls is minimal
|
|
149
|
+
* ❌ Regex not yet supported in filters
|
|
150
|
+
* 📄 Only outputs `.md` format (Markdown)
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## 📜 License
|
|
155
|
+
|
|
156
|
+
Released under the **MIT License**. Use, modify, and share freely — attribution appreciated.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 🤝 Contribute
|
|
161
|
+
|
|
162
|
+
Found a bug or have an idea?
|
|
163
|
+
Open an issue or submit a PR — contributions are always welcome!
|
|
164
|
+
|
|
171
165
|
---
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
from argparse import ArgumentParser, Namespace
|
|
2
|
+
from logging import INFO, WARNING, basicConfig, exception, getLogger, info
|
|
3
|
+
from os import chdir, curdir, getcwd, listdir, makedirs, scandir
|
|
4
|
+
from os.path import abspath, dirname, exists, getsize, isdir, join, splitext
|
|
5
|
+
from typing import List, Optional
|
|
6
|
+
|
|
7
|
+
from google.genai import Client
|
|
8
|
+
from google.genai.types import GenerateContentConfig
|
|
9
|
+
|
|
10
|
+
basicConfig(level=INFO)
|
|
11
|
+
getLogger("google_genai").setLevel(WARNING)
|
|
12
|
+
getLogger("httpx").setLevel(WARNING)
|
|
13
|
+
|
|
14
|
+
# Runtime globals initialized in main().
|
|
15
|
+
client: Optional[Client] = None
|
|
16
|
+
start_dir: str = ""
|
|
17
|
+
DOCS_BASE: str = "docs"
|
|
18
|
+
data: str = ""
|
|
19
|
+
ow: bool = False
|
|
20
|
+
|
|
21
|
+
prompt = '''
|
|
22
|
+
You are Gantavya Bansal, a senior software engineer and expert technical writer. Your task is to generate clean, professional, and well-structured `README.md` documentation in Markdown format. Use the provided filename, source code, and any existing README or folder structure as context.
|
|
23
|
+
|
|
24
|
+
Your output must be:
|
|
25
|
+
|
|
26
|
+
- Concise and easy to follow
|
|
27
|
+
- Focused on technical clarity and usability
|
|
28
|
+
- Markdown-only (no extra commentary, no code fences)
|
|
29
|
+
|
|
30
|
+
Your output must include:
|
|
31
|
+
|
|
32
|
+
1. **Project Title** – Inferred from the filename or main script
|
|
33
|
+
2. **Folder Structure** – Tree view if available, with clickable index links
|
|
34
|
+
3. **Description** – What the project does and its purpose
|
|
35
|
+
4. **How to Use** – Installation steps, CLI/API usage examples
|
|
36
|
+
5. **Technologies Used** – Languages, tools, libraries
|
|
37
|
+
6. **Architecture or Code Overview** – Key components, flow, functions, or classes
|
|
38
|
+
7. **Known Issues / Improvements** – Current limitations, TODOs
|
|
39
|
+
8. **Additional Notes or References** – Licensing, credits, related tools
|
|
40
|
+
|
|
41
|
+
Only return the final `README.md` content. Do not include any explanations, prefixes, or suffixes.
|
|
42
|
+
|
|
43
|
+
'''
|
|
44
|
+
|
|
45
|
+
avoid: List[str] = [
|
|
46
|
+
'cache', 'node', 'module', 'pkg', 'package', '@', '$', '#', '&',
|
|
47
|
+
'util', 'hook', 'component', 'python', 'compile', 'dist', 'build', 'env',
|
|
48
|
+
'docs', 'lib', 'bin', 'obj', 'out', '__pycache__', '.next', '.turbo', '.expo',
|
|
49
|
+
'.idea', '.vscode', 'coverage', 'test', 'tests', 'fixtures', 'migrations',
|
|
50
|
+
'assets', 'static', 'logs', 'debug', 'config', 'style'
|
|
51
|
+
]
|
|
52
|
+
prefix: List[str] = ['.', '-', '_', '~']
|
|
53
|
+
suffix: List[str] = [
|
|
54
|
+
'.log', '.png', '.jpg', '.jpeg', '.svg', '.ico', '.gif', '.webp',
|
|
55
|
+
'.pyc', '.class', '.zip', '.min.js', '.mp4', '.mp3', '.wav', '.pdf',
|
|
56
|
+
'.docx', '.xlsx', '.db', '.sqlite', '.bak', '.7z', '.rar', '.tar.gz',
|
|
57
|
+
'.exe', '.dll', '.so', '.ttf', '.woff', '.eot', '.swp', '.map', '.webm', '.md', '.css'
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def GenerateReadMe(file: str, code: str, readme: str) -> str:
|
|
62
|
+
"""Generate markdown docs using Gemini with fallback model sequence."""
|
|
63
|
+
if client is None:
|
|
64
|
+
return f"# {file}\n\n⚠️ Failed to generate documentation. API client is not initialized."
|
|
65
|
+
|
|
66
|
+
models: List[str] = [
|
|
67
|
+
"gemini-3.1-pro-preview",
|
|
68
|
+
"gemini-3-flash-preview",
|
|
69
|
+
"gemini-3.1-flash-lite-preview",
|
|
70
|
+
"gemini-2.5-pro",
|
|
71
|
+
"gemini-2.5-flash",
|
|
72
|
+
"gemini-2.0-flash",
|
|
73
|
+
"gemini-2.5-flash-lite",
|
|
74
|
+
"gemini-2.0-flash-lite",
|
|
75
|
+
]
|
|
76
|
+
last_error: Optional[Exception] = None
|
|
77
|
+
|
|
78
|
+
for model_name in models:
|
|
79
|
+
try:
|
|
80
|
+
response = client.models.generate_content(
|
|
81
|
+
model=model_name,
|
|
82
|
+
config=GenerateContentConfig(system_instruction=prompt),
|
|
83
|
+
contents=[
|
|
84
|
+
f"Filename: {file}",
|
|
85
|
+
f"Code:\n{code}",
|
|
86
|
+
f"Existing README (if any):\n{readme}",
|
|
87
|
+
],
|
|
88
|
+
)
|
|
89
|
+
return response.text.removeprefix('```markdown').removesuffix('```').strip()
|
|
90
|
+
except Exception as err:
|
|
91
|
+
last_error = err
|
|
92
|
+
|
|
93
|
+
exception(f"Error generating README for {file}: {last_error}")
|
|
94
|
+
return f"# {file}\n\n⚠️ Failed to generate documentation GEMINI SERVER ERROR."
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def print_tree(start_path: str = '.', prefix: str = '') -> str:
|
|
98
|
+
"""Build a filtered tree-like text representation for the given directory."""
|
|
99
|
+
try:
|
|
100
|
+
tree = ''
|
|
101
|
+
files: List[str] = []
|
|
102
|
+
folders: List[str] = []
|
|
103
|
+
|
|
104
|
+
if not isdir(start_path):
|
|
105
|
+
parent = dirname(abspath(start_path))
|
|
106
|
+
if isdir(parent):
|
|
107
|
+
start_path = parent
|
|
108
|
+
else:
|
|
109
|
+
return ""
|
|
110
|
+
|
|
111
|
+
with scandir(start_path) as entries:
|
|
112
|
+
for entry in entries:
|
|
113
|
+
if IsValid(entry.name):
|
|
114
|
+
if entry.is_dir():
|
|
115
|
+
folders.append(entry.name)
|
|
116
|
+
else:
|
|
117
|
+
files.append(entry.name)
|
|
118
|
+
|
|
119
|
+
folders.sort()
|
|
120
|
+
files.sort()
|
|
121
|
+
ordered_entries = folders + files
|
|
122
|
+
|
|
123
|
+
for index, name in enumerate(ordered_entries):
|
|
124
|
+
path = join(start_path, name)
|
|
125
|
+
is_last = index == len(ordered_entries) - 1
|
|
126
|
+
|
|
127
|
+
branch = '└── ' if is_last else '├── '
|
|
128
|
+
tree += prefix + branch + name + '\n'
|
|
129
|
+
|
|
130
|
+
if name in folders:
|
|
131
|
+
extension = ' ' if is_last else '│ '
|
|
132
|
+
tree += print_tree(path, prefix + extension)
|
|
133
|
+
|
|
134
|
+
return tree
|
|
135
|
+
except Exception as err:
|
|
136
|
+
exception(f"Error generating Tree for {start_path} dir: {err}")
|
|
137
|
+
return f"# {start_path}\n\n⚠️ Failed to generate documentation tree."
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def FolderReadMe(base: str, folders: List[str], files: List[str]) -> None:
|
|
141
|
+
"""Generate a folder-level README summary from nested files and folders."""
|
|
142
|
+
try:
|
|
143
|
+
all_content = LookReadMe(base)
|
|
144
|
+
all_content += f"\n {print_tree(start_path=base)} \n"
|
|
145
|
+
|
|
146
|
+
for folder in folders:
|
|
147
|
+
path = join(getcwd(), folder)
|
|
148
|
+
all_content += f"\n readme for folder:{folder} \n content inside: \n {LookReadMe(path)} \n"
|
|
149
|
+
|
|
150
|
+
for file in files:
|
|
151
|
+
all_content += f"\n readme for file:{file} \n content inside: {LookReadMe(file)} \n"
|
|
152
|
+
|
|
153
|
+
root_name = 'README' if base == '.' else base
|
|
154
|
+
WriteReadMe(root_name, all_content, LookReadMe(root_name))
|
|
155
|
+
info("")
|
|
156
|
+
except Exception as err:
|
|
157
|
+
exception(f"Error generating README for {base}: {err}")
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def LookReadMe(file: str) -> str:
|
|
161
|
+
"""Read an adjacent markdown file if available."""
|
|
162
|
+
try:
|
|
163
|
+
md_path = file + '.md'
|
|
164
|
+
if exists(md_path):
|
|
165
|
+
with open(md_path, 'r', encoding='utf-8') as readme:
|
|
166
|
+
return readme.read()
|
|
167
|
+
return ""
|
|
168
|
+
except Exception as err:
|
|
169
|
+
exception(f"Error reading README for {file}: {err}")
|
|
170
|
+
return f"# {file}\n\n⚠️ Failed to read {file}.md"
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def LookCode(file: str) -> str:
|
|
174
|
+
"""Read source code content from a file path."""
|
|
175
|
+
try:
|
|
176
|
+
with open(file, 'r', encoding='utf-8') as code_file:
|
|
177
|
+
return code_file.read()
|
|
178
|
+
except Exception as err:
|
|
179
|
+
exception(f"Error reading code in {file}: {err}")
|
|
180
|
+
return f"# {file}\n\n⚠️ Failed to read {file}"
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def WriteReadMe(file: str, code: str, readme: str) -> None:
|
|
184
|
+
"""Create markdown output for one file and write it to docs or root README."""
|
|
185
|
+
try:
|
|
186
|
+
rel_path = getcwd().replace(start_dir, '').lstrip('\\/').replace('\\', '/')
|
|
187
|
+
docs_dir = join(start_dir, DOCS_BASE, rel_path)
|
|
188
|
+
makedirs(docs_dir, exist_ok=True)
|
|
189
|
+
|
|
190
|
+
filename = splitext(file)[0] + '.md'
|
|
191
|
+
if 'README' in filename.upper():
|
|
192
|
+
if not ow:
|
|
193
|
+
info("skipping overwriting README")
|
|
194
|
+
full_path = join(docs_dir, 'README.md')
|
|
195
|
+
else:
|
|
196
|
+
full_path = join('README.md')
|
|
197
|
+
else:
|
|
198
|
+
full_path = join(docs_dir, filename)
|
|
199
|
+
|
|
200
|
+
generated_prompt_input = data + readme
|
|
201
|
+
with open(full_path, 'w', encoding='utf-8') as readme_file:
|
|
202
|
+
readme_file.write(GenerateReadMe(file, code, generated_prompt_input))
|
|
203
|
+
|
|
204
|
+
print(f"Written to: {filename}")
|
|
205
|
+
except Exception as err:
|
|
206
|
+
exception(f"Error writing README for {file}: {err}")
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def LookFolder(base: str) -> None:
|
|
210
|
+
"""Recursively scan folders and generate markdown docs for valid files."""
|
|
211
|
+
try:
|
|
212
|
+
chdir(base)
|
|
213
|
+
print(f"Reading Folder: {base}")
|
|
214
|
+
|
|
215
|
+
entries: List[str] = [entry for entry in listdir() if IsValid(entry)]
|
|
216
|
+
folders: List[str] = [
|
|
217
|
+
folder for folder in entries
|
|
218
|
+
if isdir(join(getcwd(), folder))
|
|
219
|
+
]
|
|
220
|
+
|
|
221
|
+
if folders:
|
|
222
|
+
print("Folders found:")
|
|
223
|
+
for folder in folders:
|
|
224
|
+
info(folder)
|
|
225
|
+
|
|
226
|
+
for folder in folders:
|
|
227
|
+
info("")
|
|
228
|
+
print(f"Opening Folder: {folder}")
|
|
229
|
+
LookFolder(folder)
|
|
230
|
+
print(f"Closing Folder: {folder}")
|
|
231
|
+
info("")
|
|
232
|
+
|
|
233
|
+
files: List[str] = [
|
|
234
|
+
file for file in entries
|
|
235
|
+
if (not isdir(join(getcwd(), file))) and (getsize(file) < 1_000_000)
|
|
236
|
+
]
|
|
237
|
+
|
|
238
|
+
if files:
|
|
239
|
+
print("Files found:")
|
|
240
|
+
for file in files:
|
|
241
|
+
info(file)
|
|
242
|
+
|
|
243
|
+
for file in files:
|
|
244
|
+
code = LookCode(file)
|
|
245
|
+
readme = LookReadMe(file)
|
|
246
|
+
WriteReadMe(file, code, readme)
|
|
247
|
+
|
|
248
|
+
FolderReadMe(base, folders, files)
|
|
249
|
+
chdir('..')
|
|
250
|
+
except Exception:
|
|
251
|
+
exception(f"Failed to read {base} folder.")
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def Look(include: str, exclude: str) -> None:
|
|
255
|
+
"""Apply user include/exclude filters to default keyword and suffix lists."""
|
|
256
|
+
try:
|
|
257
|
+
include_entries = [i.strip() for i in include.split(',') if i.strip()]
|
|
258
|
+
exclude_entries = [e.strip() for e in exclude.split(',') if e.strip()]
|
|
259
|
+
|
|
260
|
+
for include_item in include_entries:
|
|
261
|
+
avoid.append(include_item)
|
|
262
|
+
|
|
263
|
+
for exclude_item in exclude_entries:
|
|
264
|
+
if exclude_item in avoid:
|
|
265
|
+
avoid.remove(exclude_item)
|
|
266
|
+
if exclude_item in suffix:
|
|
267
|
+
suffix.remove(exclude_item)
|
|
268
|
+
except Exception:
|
|
269
|
+
exception("Error in use with args --include || --exclude")
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def IsValid(entry: str) -> bool:
|
|
273
|
+
"""Return True when file/folder name passes configured filters."""
|
|
274
|
+
name = entry.lower()
|
|
275
|
+
return (
|
|
276
|
+
not any(name.startswith(sw) for sw in prefix)
|
|
277
|
+
and not any(name.endswith(ew) for ew in suffix)
|
|
278
|
+
and not any(kw in name for kw in avoid)
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def main() -> None:
|
|
283
|
+
"""CLI entrypoint for docs generation workflow."""
|
|
284
|
+
try:
|
|
285
|
+
parser = ArgumentParser(
|
|
286
|
+
description="Auto-generate documentation from source code and folder structure."
|
|
287
|
+
)
|
|
288
|
+
parser.add_argument(
|
|
289
|
+
"-p", "--path",
|
|
290
|
+
type=str,
|
|
291
|
+
default=".",
|
|
292
|
+
help="Root path to scan (default: current directory)"
|
|
293
|
+
)
|
|
294
|
+
parser.add_argument(
|
|
295
|
+
"--name",
|
|
296
|
+
type=str,
|
|
297
|
+
default="My Project",
|
|
298
|
+
help="Project name to include in README"
|
|
299
|
+
)
|
|
300
|
+
parser.add_argument(
|
|
301
|
+
"--description",
|
|
302
|
+
type=str,
|
|
303
|
+
default="No description provided.",
|
|
304
|
+
help="Short description of the project"
|
|
305
|
+
)
|
|
306
|
+
parser.add_argument(
|
|
307
|
+
"--authors",
|
|
308
|
+
type=str,
|
|
309
|
+
default="Anonymous",
|
|
310
|
+
help="Comma-separated list of author names"
|
|
311
|
+
)
|
|
312
|
+
parser.add_argument(
|
|
313
|
+
"--keywords",
|
|
314
|
+
type=str,
|
|
315
|
+
default="",
|
|
316
|
+
help="Comma-separated keywords (e.g., cli, docs, auto)"
|
|
317
|
+
)
|
|
318
|
+
parser.add_argument(
|
|
319
|
+
"--overwrite",
|
|
320
|
+
action="store_true",
|
|
321
|
+
help="Overwrite existing README files (default: False)"
|
|
322
|
+
)
|
|
323
|
+
parser.add_argument(
|
|
324
|
+
"--output",
|
|
325
|
+
type=str,
|
|
326
|
+
default='docs',
|
|
327
|
+
help="Output dir where docs to be stored (default: docs)"
|
|
328
|
+
)
|
|
329
|
+
parser.add_argument(
|
|
330
|
+
"--exclude",
|
|
331
|
+
type=str,
|
|
332
|
+
default='',
|
|
333
|
+
help="Folders, files, extensionse to exclude ((e.g., docs, ext, setting, config)"
|
|
334
|
+
)
|
|
335
|
+
parser.add_argument(
|
|
336
|
+
"--include",
|
|
337
|
+
type=str,
|
|
338
|
+
default='',
|
|
339
|
+
help="Folders, files, extensionse to include ((e.g., docs, ext, setting, config)"
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
global client
|
|
343
|
+
global start_dir
|
|
344
|
+
global DOCS_BASE
|
|
345
|
+
global data
|
|
346
|
+
global ow
|
|
347
|
+
|
|
348
|
+
args: Namespace = parser.parse_args()
|
|
349
|
+
start_dir = getcwd()
|
|
350
|
+
|
|
351
|
+
ow = args.overwrite
|
|
352
|
+
DOCS_BASE = args.output
|
|
353
|
+
Look(include=args.include, exclude=args.exclude)
|
|
354
|
+
|
|
355
|
+
if not exists(DOCS_BASE):
|
|
356
|
+
makedirs(DOCS_BASE)
|
|
357
|
+
|
|
358
|
+
avoid.append(DOCS_BASE)
|
|
359
|
+
data = (
|
|
360
|
+
f"name: {args.name}\n"
|
|
361
|
+
f"description: {args.description}\n"
|
|
362
|
+
f"authors: {args.authors}\n"
|
|
363
|
+
f"keywords: {args.keywords}"
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
client = Client(api_key=input("Paste your Google Gemini API Key here:").strip())
|
|
367
|
+
print(f"📁 Starting in: {args.path}")
|
|
368
|
+
makedirs(DOCS_BASE, exist_ok=True)
|
|
369
|
+
chdir(args.path)
|
|
370
|
+
LookFolder(curdir)
|
|
371
|
+
print("✅ Documentation generated successfully.")
|
|
372
|
+
except Exception:
|
|
373
|
+
exception("Error during execution. Try using --help.")
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
if __name__ == "__main__":
|
|
377
|
+
main()
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devDocs
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.0
|
|
4
4
|
Summary: AI-powered CLI tool that builds professional '*.md' documentation files of a project for internal teams using the Google Gemini API.
|
|
5
|
-
Author: Gantavya Bansal
|
|
6
5
|
Author-email: Gantavya Bansal <gantavyaoo@gmail.com>
|
|
7
|
-
License: MIT
|
|
6
|
+
License-Expression: MIT
|
|
8
7
|
Project-URL: Homepage, https://github.com/bgantavya/devDocs
|
|
9
8
|
Project-URL: Repository, https://github.com/bgantavya/devDocs
|
|
10
9
|
Project-URL: Issues, https://github.com/bgantavya/devDocs/issues
|
|
@@ -17,7 +16,6 @@ Classifier: Intended Audience :: Information Technology
|
|
|
17
16
|
Classifier: Topic :: Documentation
|
|
18
17
|
Classifier: Topic :: Software Development :: Code Generators
|
|
19
18
|
Classifier: Topic :: Software Development :: Documentation
|
|
20
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
21
19
|
Classifier: Programming Language :: Python :: 3
|
|
22
20
|
Classifier: Programming Language :: Python :: 3.8
|
|
23
21
|
Classifier: Programming Language :: Python :: 3.9
|
|
@@ -28,8 +26,6 @@ Requires-Python: >=3.8
|
|
|
28
26
|
Description-Content-Type: text/markdown
|
|
29
27
|
Requires-Dist: google-genai
|
|
30
28
|
Requires-Dist: httpx
|
|
31
|
-
Dynamic: author
|
|
32
|
-
Dynamic: requires-python
|
|
33
29
|
|
|
34
30
|
|
|
35
31
|
---
|
|
@@ -53,15 +49,14 @@ Before and after running `devDocs`:
|
|
|
53
49
|
```bash
|
|
54
50
|
your-project/
|
|
55
51
|
├── src/
|
|
56
|
-
│ ├──
|
|
57
|
-
│ └──
|
|
52
|
+
│ ├── code
|
|
53
|
+
│ └── s/es
|
|
58
54
|
├── tests/
|
|
59
55
|
├── requirements.txt
|
|
60
56
|
├── LICENSE
|
|
61
57
|
├── docs/ # ← Generated by devDocs
|
|
62
58
|
└── README.md # ← Overwritten by devDocs (if chosen)
|
|
63
59
|
```
|
|
64
|
-
|
|
65
60
|
---
|
|
66
61
|
|
|
67
62
|
## ⚙️ How It Works
|
|
@@ -71,11 +66,6 @@ your-project/
|
|
|
71
66
|
3. **Generates** documentation via Google Gemini
|
|
72
67
|
4. **Saves** output in Markdown format
|
|
73
68
|
|
|
74
|
-
### Optional Features
|
|
75
|
-
|
|
76
|
-
* Preserve existing README (unless `--overwrite` is set)
|
|
77
|
-
* Include/exclude specific files or folders via filters
|
|
78
|
-
|
|
79
69
|
---
|
|
80
70
|
|
|
81
71
|
## 📦 Installation
|
|
@@ -1,56 +1,55 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
-
build-backend = "setuptools.build_meta"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name = "devDocs"
|
|
7
|
-
version = "
|
|
8
|
-
description = "AI-powered CLI tool that builds professional '*.md' documentation files of a project for internal teams using the Google Gemini API."
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.8"
|
|
11
|
-
license =
|
|
12
|
-
|
|
13
|
-
authors = [
|
|
14
|
-
{ name = "Gantavya Bansal", email = "gantavyaoo@gmail.com" }
|
|
15
|
-
]
|
|
16
|
-
|
|
17
|
-
keywords = [
|
|
18
|
-
"cli", "documentation", "readme", "generator",
|
|
19
|
-
"google-gemini", "ai", "markdown", "docs-generator",
|
|
20
|
-
"auto-readme", "open-source"
|
|
21
|
-
]
|
|
22
|
-
|
|
23
|
-
classifiers = [
|
|
24
|
-
"Development Status :: 4 - Beta",
|
|
25
|
-
"Environment :: Console",
|
|
26
|
-
"Intended Audience :: Developers",
|
|
27
|
-
"Intended Audience :: Information Technology",
|
|
28
|
-
"Topic :: Documentation",
|
|
29
|
-
"Topic :: Software Development :: Code Generators",
|
|
30
|
-
"Topic :: Software Development :: Documentation",
|
|
31
|
-
"
|
|
32
|
-
"Programming Language :: Python :: 3",
|
|
33
|
-
"Programming Language :: Python :: 3.
|
|
34
|
-
"Programming Language :: Python :: 3.
|
|
35
|
-
"Programming Language :: Python :: 3.
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
[
|
|
55
|
-
|
|
56
|
-
include-package-data = true
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "devDocs"
|
|
7
|
+
version = "3.0.0"
|
|
8
|
+
description = "AI-powered CLI tool that builds professional '*.md' documentation files of a project for internal teams using the Google Gemini API."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Gantavya Bansal", email = "gantavyaoo@gmail.com" }
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
keywords = [
|
|
18
|
+
"cli", "documentation", "readme", "generator",
|
|
19
|
+
"google-gemini", "ai", "markdown", "docs-generator",
|
|
20
|
+
"auto-readme", "open-source"
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Development Status :: 4 - Beta",
|
|
25
|
+
"Environment :: Console",
|
|
26
|
+
"Intended Audience :: Developers",
|
|
27
|
+
"Intended Audience :: Information Technology",
|
|
28
|
+
"Topic :: Documentation",
|
|
29
|
+
"Topic :: Software Development :: Code Generators",
|
|
30
|
+
"Topic :: Software Development :: Documentation",
|
|
31
|
+
"Programming Language :: Python :: 3",
|
|
32
|
+
"Programming Language :: Python :: 3.8",
|
|
33
|
+
"Programming Language :: Python :: 3.9",
|
|
34
|
+
"Programming Language :: Python :: 3.10",
|
|
35
|
+
"Programming Language :: Python :: 3.11",
|
|
36
|
+
"Operating System :: OS Independent"
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
dependencies = [
|
|
40
|
+
"google-genai",
|
|
41
|
+
"httpx"
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[project.urls]
|
|
45
|
+
Homepage = "https://github.com/bgantavya/devDocs"
|
|
46
|
+
Repository = "https://github.com/bgantavya/devDocs"
|
|
47
|
+
Issues = "https://github.com/bgantavya/devDocs/issues"
|
|
48
|
+
Documentation = "https://github.com/bgantavya/devDocs#readme"
|
|
49
|
+
|
|
50
|
+
[project.scripts]
|
|
51
|
+
devDocs = "devDocs.cli:main"
|
|
52
|
+
|
|
53
|
+
[tool.setuptools]
|
|
54
|
+
packages = ["devDocs"]
|
|
55
|
+
include-package-data = true
|
devdocs-3.0.0/setup.py
ADDED
devdocs-2.0.6/devDocs/cli.py
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
k='docs'
|
|
2
|
-
Y='utf-8'
|
|
3
|
-
X='README'
|
|
4
|
-
W=any
|
|
5
|
-
V=open
|
|
6
|
-
Q='.md'
|
|
7
|
-
N='.'
|
|
8
|
-
G=str
|
|
9
|
-
F=print
|
|
10
|
-
B=''
|
|
11
|
-
A=Exception
|
|
12
|
-
from logging import basicConfig as l,info as H,WARNING as Z,INFO,getLogger as a,exception as E
|
|
13
|
-
from os import listdir as m,getcwd as J,chdir as R,scandir as n,curdir as o,makedirs as S
|
|
14
|
-
from os.path import isdir as O,join as C,splitext as p,exists as b,getsize as q,dirname as c,abspath as d
|
|
15
|
-
from google.genai import Client as r
|
|
16
|
-
from google.genai.types import GenerateContentConfig as D
|
|
17
|
-
from argparse import ArgumentParser as s
|
|
18
|
-
from time import sleep
|
|
19
|
-
l(level=INFO)
|
|
20
|
-
a('google_genai').setLevel(Z)
|
|
21
|
-
a('httpx').setLevel(Z)
|
|
22
|
-
P='\nYou are Gantavya Bansal, a senior software engineer and expert technical writer. Your task is to generate clean, professional, and well-structured `README.md` documentation in Markdown format. Use the provided filename, source code, and any existing README or folder structure as context.\n\nYour output must be:\n\n- Concise and easy to follow\n- Focused on technical clarity and usability\n- Markdown-only (no extra commentary, no code fences)\n\nYour output must include:\n\n1. **Project Title** – Inferred from the filename or main script\n2. **Folder Structure** – Tree view if available, with clickable index links\n3. **Description** – What the project does and its purpose\n4. **How to Use** – Installation steps, CLI/API usage examples\n5. **Technologies Used** – Languages, tools, libraries\n6. **Architecture or Code Overview** – Key components, flow, functions, or classes\n7. **Known Issues / Improvements** – Current limitations, TODOs\n8. **Additional Notes or References** – Licensing, credits, related tools\n\nOnly return the final `README.md` content. Do not include any explanations, prefixes, or suffixes.\n\n '
|
|
23
|
-
def t(file,code,readme):
|
|
24
|
-
J='```';I='```markdown';G=readme;F=code;C=file
|
|
25
|
-
try:B=M.models.generate_content(model='gemini-2.0-flash-lite',config=D(system_instruction=P),contents=[f"Filename: {C}",f"Code:\n{F}",f"Existing README (if any):\n{G}"]);return B.text.removeprefix(I).removesuffix(J).strip()
|
|
26
|
-
except A as H:
|
|
27
|
-
try:B=M.models.generate_content(model='gemini-2.0-flash',config=D(system_instruction=P),contents=[f"Filename: {C}",f"Code:\n{F}",f"Existing README (if any):\n{G}"]);return B.text.removeprefix(I).removesuffix(J).strip()
|
|
28
|
-
except A as H:
|
|
29
|
-
try:B=M.models.generate_content(model='gemini-2.5-flash-lite',config=D(system_instruction=P),contents=[f"Filename: {C}",f"Code:\n{F}",f"Existing README (if any):\n{G}"]);return B.text.removeprefix(I).removesuffix(J).strip()
|
|
30
|
-
except A as H:
|
|
31
|
-
try:B=M.models.generate_content(model='gemini-2.5-flash',config=D(system_instruction=P),contents=[f"Filename: {C}",f"Code:\n{F}",f"Existing README (if any):\n{G}"]);return B.text.removeprefix(I).removesuffix(J).strip()
|
|
32
|
-
except A as H:E(f"Error generating README for {C}: {H}");return f"# {C}\n\n⚠️ Failed to generate documentation GEMINI SERVER ERROR."
|
|
33
|
-
def e(start_path=N,prefix=B):
|
|
34
|
-
L=prefix;D=start_path
|
|
35
|
-
try:
|
|
36
|
-
I=B;J=[];F=[]
|
|
37
|
-
if not O(D):
|
|
38
|
-
if O(c(d(D))):D=c(d(D))
|
|
39
|
-
else:return B
|
|
40
|
-
with n(D)as G:
|
|
41
|
-
for H in G:
|
|
42
|
-
if h(H.name):
|
|
43
|
-
if H.is_dir():F.append(H.name)
|
|
44
|
-
else:J.append(H.name)
|
|
45
|
-
F.sort();J.sort();G=F+J
|
|
46
|
-
for(N,K)in enumerate(G):
|
|
47
|
-
P=C(D,K);M=N==len(G)-1;Q='└── 'if M else'├── ';I+=L+Q+K+'\n'
|
|
48
|
-
if K in F:R=' 'if M else'│ ';I+=e(P,L+R)
|
|
49
|
-
return I
|
|
50
|
-
except A as S:E(f"Error generating Tree for {D} dir: {S}");return f"# {D}\n\n⚠️ Failed to generate documentation tree."
|
|
51
|
-
def u(base,folders,files):
|
|
52
|
-
I=files;G=folders;D=base
|
|
53
|
-
try:
|
|
54
|
-
F=K(D);F+=f"\n {e(start_path=D)} \n"
|
|
55
|
-
if G:
|
|
56
|
-
for L in G:O=C(J(),L);F+=f"\n readme for folder:{L} \n content inside: \n {K(O)} \n"
|
|
57
|
-
if I:
|
|
58
|
-
for M in I:F+=f"\n readme for file:{M} \n content inside: {K(M)} \n"
|
|
59
|
-
f(X if D==N else D,F,K(X if D==N else D));H(B)
|
|
60
|
-
except A as P:E(f"Error generating README for {D}: {P}")
|
|
61
|
-
def K(file):
|
|
62
|
-
C=file
|
|
63
|
-
try:
|
|
64
|
-
if b(C+Q):
|
|
65
|
-
with V(C+Q,'r',encoding=Y)as D:return D.read()
|
|
66
|
-
else:return B
|
|
67
|
-
except A as F:E(f"Error reading README for {C}: {F}");return f"# {C}\n\n⚠️ Failed to read {C}.md"
|
|
68
|
-
def v(file):
|
|
69
|
-
B=file
|
|
70
|
-
try:
|
|
71
|
-
with V(B,'r',encoding=Y)as C:return C.read()
|
|
72
|
-
except A as D:E(f"Error reading code in {B}: {D}");return f"# {B}\n\n⚠️ Failed to read {B}"
|
|
73
|
-
def f(file,code,readme):
|
|
74
|
-
N='README.md';G=readme;D=file
|
|
75
|
-
try:
|
|
76
|
-
O=J().replace(U,B).lstrip('\\/').replace('\\','/');K=C(U,I,O);S(K,exist_ok=True);L=p(D)[0]+Q
|
|
77
|
-
if X in L.upper():
|
|
78
|
-
if not j:H('skipping overwriting README');M=C(K,N)
|
|
79
|
-
else:M=C(N)
|
|
80
|
-
else:M=C(K,L)
|
|
81
|
-
G=i+G
|
|
82
|
-
with V(M,'w',encoding=Y)as P:P.write(t(D,code,G))
|
|
83
|
-
F(f"Written to: {L}")
|
|
84
|
-
except A as R:E(f"Error writing README for {D}: {R}")
|
|
85
|
-
L=['cache','node','module','pkg','package','@','$','#','&','util','hook','component','python','compile','dist','build','env',k,'lib','bin','obj','out','__pycache__','.next','.turbo','.expo','.idea','.vscode','coverage','test','tests','fixtures','migrations','assets','static','logs','debug','config','style']
|
|
86
|
-
w=[N,'-','_','~']
|
|
87
|
-
T=['.log','.png','.jpg','.jpeg','.svg','.ico','.gif','.webp','.pyc','.class','.zip','.min.js','.mp4','.mp3','.wav','.pdf','.docx','.xlsx','.db','.sqlite','.bak','.7z','.rar','.tar.gz','.exe','.dll','.so','.ttf','.woff','.eot','.swp','.map','.webm',Q,'.css']
|
|
88
|
-
def g(base):
|
|
89
|
-
I=base
|
|
90
|
-
try:
|
|
91
|
-
R(I);F(f"Reading Folder: {I}");N=[A for A in m()if h(A)];L=[A for A in N if O(C(J(),A))]
|
|
92
|
-
if L:
|
|
93
|
-
F('Folders found:')
|
|
94
|
-
for D in L:H(D)
|
|
95
|
-
for D in L:H(B);F(f"Opening Folder: {D}");g(D);F(f"Closing Folder: {D}");H(B)
|
|
96
|
-
M=[A for A in N if not O(C(J(),A))and q(A)<1000000]
|
|
97
|
-
if M:
|
|
98
|
-
F('Files found:')
|
|
99
|
-
for G in M:H(G)
|
|
100
|
-
for G in M:P=v(G);Q=K(G);f(G,P,Q)
|
|
101
|
-
u(I,L,M);R('..')
|
|
102
|
-
except A as S:E(f"Failed to read {I} folder.")
|
|
103
|
-
def x(include,exclude):
|
|
104
|
-
D=exclude;C=include
|
|
105
|
-
try:
|
|
106
|
-
C=[A.strip()for A in C.split(',')if A.strip()];D=[A.strip()for A in D.split(',')if A.strip()]
|
|
107
|
-
for F in C:L.append(F.strip())
|
|
108
|
-
for B in D:
|
|
109
|
-
if B in L:L.remove(B.strip())
|
|
110
|
-
if B in T:T.remove(B.strip())
|
|
111
|
-
except A as G:E('Error in use with args --include || --exclude')
|
|
112
|
-
def h(entry):A=entry.lower();return not W(A.startswith(B)for B in w)and not W(A.endswith(B)for B in T)and not W(B in A for B in L)
|
|
113
|
-
def y():
|
|
114
|
-
try:
|
|
115
|
-
C=s(description='Auto-generate documentation from source code and folder structure.');C.add_argument('-p','--path',type=G,default=N,help='Root path to scan (default: current directory)');C.add_argument('--name',type=G,default='My Project',help='Project name to include in README');C.add_argument('--description',type=G,default='No description provided.',help='Short description of the project');C.add_argument('--authors',type=G,default='Anonymous',help='Comma-separated list of author names');C.add_argument('--keywords',type=G,default=B,help='Comma-separated keywords (e.g., cli, docs, auto)');C.add_argument('--overwrite',action='store_true',help='Overwrite existing README files (default: False)');C.add_argument('--output',type=G,default=k,help='Output dir where docs to be stored (default: docs)');C.add_argument('--exclude',type=G,default=B,help='Folders, files, extensionse to exclude ((e.g., docs, ext, setting, config)');C.add_argument('--include',type=G,default=B,help='Folders, files, extensionse to include ((e.g., docs, ext, setting, config)');global M;global U;global I;global i;global j;D=C.parse_args();U=J();j=D.overwrite;I=D.output;x(include=D.include,exclude=D.exclude)
|
|
116
|
-
if not b(I):S(I)
|
|
117
|
-
L.append(I);i=f"name: {D.name}\ndescription: {D.description}\nauthors: {D.authors}\nkeywords: {D.keywords}";M=r(api_key=input('Paste your Google Gemini API Key here:').strip());F(f"📁 Starting in: {D.path}");S(I,exist_ok=True);R(D.path);g(o);F('✅ Documentation generated successfully.')
|
|
118
|
-
except A as H:E('Error during execution. Try using --help.')
|
|
119
|
-
if __name__=='__main__':y()
|
devdocs-2.0.6/setup.py
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
from setuptools import setup,find_packages as A
|
|
2
|
-
setup(name='devDocs',version='2.0.6',packages=A(),install_requires=['google-generativeai'],entry_points={'console_scripts':['devDocs=devDocs.cli:x']},author='Gantavya Bansal',description="Auto-generate Project's markdown documentation using Gemini AI for Internal teams.",long_description=open('README.md',encoding='utf-8').read(),long_description_content_type='text/markdown',license='MIT',python_requires='>=3.8',classifiers=['Programming Language :: Python :: 3','License :: OSI Approved :: MIT License'])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|