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.
@@ -1,10 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devDocs
3
- Version: 2.0.6
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
- │ ├── main.py
57
- │ └── utils.py
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
- │ ├── main.py
24
- │ └── utils.py
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
- ## ⚙️ How It Works
35
-
36
- 1. **Scans** project directory and source files
37
- 2. **Parses** content (code, comments, old README)
38
- 3. **Generates** documentation via Google Gemini
39
- 4. **Saves** output in Markdown format
40
-
41
- ### Optional Features
42
-
43
- * Preserve existing README (unless `--overwrite` is set)
44
- * Include/exclude specific files or folders via filters
45
-
46
- ---
47
-
48
- ## 📦 Installation
49
-
50
- Install via pip:
51
-
52
- ```bash
53
- pip install devDocs
54
- ```
55
-
56
- ---
57
-
58
- ## 🔑 Requirements
59
-
60
- * Python 3.8+
61
- * Google Gemini API Key (get one at [Google AI Studio](https://aistudio.google.com/))
62
-
63
- ---
64
-
65
- ## 🚀 Usage
66
-
67
- Run inside your project’s root:
68
-
69
- ```bash
70
- devDocs [OPTIONS]
71
- ```
72
-
73
- Paste your **Gemini API key** when prompted.
74
-
75
- ### CLI Options
76
-
77
- | Option | Description |
78
- | --------------- | ------------------------------------------------- |
79
- | `--path` | Root folder to scan (default: `.`) |
80
- | `--name` | Project name to display in the README |
81
- | `--description` | Short project summary |
82
- | `--authors` | Comma-separated list of authors |
83
- | `--keywords` | Comma-separated keywords (e.g., cli, docs, ai) |
84
- | `--overwrite` | Overwrite existing `README.md` (default: False) |
85
- | `--output` | Output folder (default: `docs/`) |
86
- | `--exclude` | Comma-separated paths/extensions to exclude |
87
- | `--include` | Comma-separated paths/extensions to force include |
88
-
89
- ---
90
-
91
- ### Example
92
-
93
- ```bash
94
- devDocs --path . \
95
- --name "Cool Dev Tool" \
96
- --description "Generate AI-based READMEs effortlessly" \
97
- --authors "Gantavya Bansal" \
98
- --keywords "cli, docs, automation" \
99
- --output docs \
100
- --overwrite
101
- ```
102
-
103
- ---
104
-
105
- ## 🧠 Key Features
106
-
107
- ✅ Auto-generates structured `README.md`
108
- ✅ Respects original files unless `--overwrite`
109
- ✅ Fine-grained include/exclude control
110
- Generates a visual folder tree
111
- ✅ Clean output in a dedicated `--output` folder
112
- Backed by Google Gemini for high-quality results
113
-
114
- ---
115
-
116
- ## 🧱 Tech Stack
117
-
118
- * Python 3.8+
119
- * [`google-genai`](https://pypi.org/project/google-generativeai/)
120
- * Built-in: `argparse`, `os`, `logging`, `time`
121
-
122
- ---
123
-
124
- ## 🛠️ Dev Notes
125
-
126
- ### Workflow
127
-
128
- ```
129
- CLI args → Filter files → Extract context → Call Gemini → Write docs
130
- ```
131
-
132
- ### API Prompt Template
133
-
134
- ```python
135
- system_instruction = '''
136
- You are Gantavya Bansal, a senior engineer and technical writer.
137
- Generate professional Markdown documentation using context from code and folder structure.
138
- Include:
139
- - Title
140
- - Folder Tree
141
- - Description
142
- - Usage
143
- - Tech Stack
144
- - Known Issues
145
- - Licensing
146
- '''
147
- ```
148
-
149
- ---
150
-
151
- ## ⚠️ Limitations
152
-
153
- * 📶 Requires internet (for Gemini API)
154
- * 🔁 Retry logic for failed API calls is minimal
155
- * ❌ Regex not yet supported in filters
156
- * 📄 Only outputs `.md` format (Markdown)
157
-
158
- ---
159
-
160
- ## 📜 License
161
-
162
- Released under the **MIT License**. Use, modify, and share freely — attribution appreciated.
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: 2.0.6
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
- │ ├── main.py
57
- │ └── utils.py
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
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ devDocs = devDocs.cli:main
@@ -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 = "2.0.6"
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 = { text = "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
- "License :: OSI Approved :: MIT License",
32
- "Programming Language :: Python :: 3",
33
- "Programming Language :: Python :: 3.8",
34
- "Programming Language :: Python :: 3.9",
35
- "Programming Language :: Python :: 3.10",
36
- "Programming Language :: Python :: 3.11",
37
- "Operating System :: OS Independent"
38
- ]
39
-
40
- dependencies = [
41
- "google-genai",
42
- "httpx"
43
- ]
44
-
45
- [project.urls]
46
- Homepage = "https://github.com/bgantavya/devDocs"
47
- Repository = "https://github.com/bgantavya/devDocs"
48
- Issues = "https://github.com/bgantavya/devDocs/issues"
49
- Documentation = "https://github.com/bgantavya/devDocs#readme"
50
-
51
- [project.scripts]
52
- devDocs = "devDocs.cli:x"
53
-
54
- [tool.setuptools]
55
- packages = ["devDocs"]
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
@@ -0,0 +1,3 @@
1
+ from setuptools import setup
2
+
3
+ setup()
@@ -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()
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- devDocs = devDocs.cli:x
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