gnost 0.1.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.
- gnost-0.1.0/LICENSE +21 -0
- gnost-0.1.0/PKG-INFO +126 -0
- gnost-0.1.0/README.md +113 -0
- gnost-0.1.0/gnost/__init__.py +1 -0
- gnost-0.1.0/gnost/cli/__init__.py +3 -0
- gnost-0.1.0/gnost/cli/app.py +111 -0
- gnost-0.1.0/gnost/cli/commands/__init__.py +3 -0
- gnost-0.1.0/gnost/cli/commands/onboard.py +94 -0
- gnost-0.1.0/gnost/config/__init__.py +0 -0
- gnost-0.1.0/gnost/config/languages.py +23 -0
- gnost-0.1.0/gnost/core/__init__.py +0 -0
- gnost-0.1.0/gnost/core/counter.py +23 -0
- gnost-0.1.0/gnost/core/flow.py +130 -0
- gnost-0.1.0/gnost/core/graph.py +124 -0
- gnost-0.1.0/gnost/core/ranker.py +115 -0
- gnost-0.1.0/gnost/languages/base.py +80 -0
- gnost-0.1.0/gnost/languages/java.py +82 -0
- gnost-0.1.0/gnost/languages/javascript.py +83 -0
- gnost-0.1.0/gnost/languages/python.py +105 -0
- gnost-0.1.0/gnost/languages/typescript.py +6 -0
- gnost-0.1.0/gnost/plugins/__init__.py +3 -0
- gnost-0.1.0/gnost/plugins/base.py +5 -0
- gnost-0.1.0/gnost/reporters/__init__.py +3 -0
- gnost-0.1.0/gnost/reporters/files.py +18 -0
- gnost-0.1.0/gnost/reporters/folders.py +18 -0
- gnost-0.1.0/gnost/reporters/loc_summary.py +19 -0
- gnost-0.1.0/gnost/reporters/markdown.py +138 -0
- gnost-0.1.0/gnost/reporters/mermaid.py +75 -0
- gnost-0.1.0/gnost/reporters/stats.py +13 -0
- gnost-0.1.0/gnost/reporters/summary.py +144 -0
- gnost-0.1.0/gnost/scanner/__init__.py +4 -0
- gnost-0.1.0/gnost/scanner/classify.py +13 -0
- gnost-0.1.0/gnost/scanner/engine.py +107 -0
- gnost-0.1.0/gnost/scanner/filters.py +82 -0
- gnost-0.1.0/gnost/scanner/loc.py +78 -0
- gnost-0.1.0/gnost/scanner/models.py +22 -0
- gnost-0.1.0/gnost/utils/__init__.py +0 -0
- gnost-0.1.0/gnost/utils/printer.py +46 -0
- gnost-0.1.0/gnost/utils/progress.py +20 -0
- gnost-0.1.0/gnost.egg-info/PKG-INFO +126 -0
- gnost-0.1.0/gnost.egg-info/SOURCES.txt +45 -0
- gnost-0.1.0/gnost.egg-info/dependency_links.txt +1 -0
- gnost-0.1.0/gnost.egg-info/entry_points.txt +2 -0
- gnost-0.1.0/gnost.egg-info/requires.txt +2 -0
- gnost-0.1.0/gnost.egg-info/top_level.txt +1 -0
- gnost-0.1.0/pyproject.toml +18 -0
- gnost-0.1.0/setup.cfg +4 -0
gnost-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Mohd Zain
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
gnost-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gnost
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: GNOST — Codebase Knowledge
|
|
5
|
+
Author-email: Mohd Zain <zainmohd1998@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.8
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: rich
|
|
11
|
+
Requires-Dist: tqdm
|
|
12
|
+
Dynamic: license-file
|
|
13
|
+
|
|
14
|
+
# GNOST — Codebase Knowledge
|
|
15
|
+

|
|
16
|
+

|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
GNOST helps developers understand unfamiliar codebases by automatically identifying **entry points**, **execution flow**, and **core logic**.
|
|
21
|
+
|
|
22
|
+
It is designed for **first-day onboarding**, not just code statistics.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## What GNOST Does
|
|
27
|
+
|
|
28
|
+
- Detects **where execution starts**
|
|
29
|
+
- Infers **high-level execution flow**
|
|
30
|
+
- Identifies **hotspot files** (most important code)
|
|
31
|
+
- Generates **onboarding documentation**
|
|
32
|
+
- Produces **Mermaid flow diagrams**
|
|
33
|
+
- Works across multiple languages
|
|
34
|
+
|
|
35
|
+
Supported languages:
|
|
36
|
+
- Python
|
|
37
|
+
- JavaScript
|
|
38
|
+
- TypeScript
|
|
39
|
+
- Java
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install gnost
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Quick Start
|
|
50
|
+
```bash
|
|
51
|
+
gnost onboard .
|
|
52
|
+
```
|
|
53
|
+
This will:
|
|
54
|
+
- Print a human-readable onboarding summary
|
|
55
|
+
- Generate ONBOARD.md
|
|
56
|
+
- Generate an execution flow diagram
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
```bash
|
|
60
|
+
gnost summary [path]
|
|
61
|
+
gnost stats [path]
|
|
62
|
+
gnost folders [path]
|
|
63
|
+
gnost files [path] --top 10
|
|
64
|
+
gnost onboard [path]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Key Commands
|
|
68
|
+
- `summary` Show a high-level project summary
|
|
69
|
+
- `stats` Show detailed language statistics
|
|
70
|
+
- `folders` Show LOC grouped by folder
|
|
71
|
+
- `files` Show largest files by LOC
|
|
72
|
+
- `onboard` Generate onboarding summary and flow diagrams
|
|
73
|
+
- `version` Display GNOST version
|
|
74
|
+
|
|
75
|
+
## Onboarding & Flow Analysis
|
|
76
|
+
- Generate onboarding documentation:
|
|
77
|
+
```bash
|
|
78
|
+
gnost onboard .
|
|
79
|
+
```
|
|
80
|
+
- Generate only a Mermaid flow diagram:
|
|
81
|
+
```bash
|
|
82
|
+
gnost onboard . --mermaid
|
|
83
|
+
```
|
|
84
|
+
This produces:
|
|
85
|
+
- ONBOARD.md — onboarding guide
|
|
86
|
+
- FLOW.mmd — pure Mermaid flow diagram
|
|
87
|
+
|
|
88
|
+
### Options
|
|
89
|
+
- `--include` Comma-separated folders to include
|
|
90
|
+
- `--exclude` Comma-separated folders to exclude
|
|
91
|
+
- `--top` Number of files to show with files
|
|
92
|
+
- `--version` Show version and exit
|
|
93
|
+
- `--help` Show help
|
|
94
|
+
|
|
95
|
+
## examples
|
|
96
|
+
```bash
|
|
97
|
+
gnost summary .
|
|
98
|
+
gnost stats .
|
|
99
|
+
gnost onboard .
|
|
100
|
+
gnost onboard . --mermaid
|
|
101
|
+
gnost files src --top 20
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Philosophy
|
|
105
|
+
GNOST is not a **static analyzer or linter**.
|
|
106
|
+
|
|
107
|
+
It focuses on:
|
|
108
|
+
- Mental model generation
|
|
109
|
+
- Execution understanding
|
|
110
|
+
- Developer onboarding
|
|
111
|
+
|
|
112
|
+
It uses **heuristic-based static analysis** to stay fast, simple, and language-agnostic.
|
|
113
|
+
|
|
114
|
+
## Roadmap
|
|
115
|
+
|
|
116
|
+
### v0.2.0 (Planned)
|
|
117
|
+
|
|
118
|
+
- Hotspot visualization in Mermaid diagrams
|
|
119
|
+
- Standalone `gnost hotspots` command
|
|
120
|
+
- Improved JavaScript / TypeScript import resolution
|
|
121
|
+
- Better framework awareness (Express, Spring MVC)
|
|
122
|
+
- Optional Tree-sitter based parsing for deeper analysis
|
|
123
|
+
- GitHub Action enhancements (PR comments, annotations)
|
|
124
|
+
|
|
125
|
+
## License
|
|
126
|
+
MIT License
|
gnost-0.1.0/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# GNOST — Codebase Knowledge
|
|
2
|
+

|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
GNOST helps developers understand unfamiliar codebases by automatically identifying **entry points**, **execution flow**, and **core logic**.
|
|
8
|
+
|
|
9
|
+
It is designed for **first-day onboarding**, not just code statistics.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## What GNOST Does
|
|
14
|
+
|
|
15
|
+
- Detects **where execution starts**
|
|
16
|
+
- Infers **high-level execution flow**
|
|
17
|
+
- Identifies **hotspot files** (most important code)
|
|
18
|
+
- Generates **onboarding documentation**
|
|
19
|
+
- Produces **Mermaid flow diagrams**
|
|
20
|
+
- Works across multiple languages
|
|
21
|
+
|
|
22
|
+
Supported languages:
|
|
23
|
+
- Python
|
|
24
|
+
- JavaScript
|
|
25
|
+
- TypeScript
|
|
26
|
+
- Java
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install gnost
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
```bash
|
|
38
|
+
gnost onboard .
|
|
39
|
+
```
|
|
40
|
+
This will:
|
|
41
|
+
- Print a human-readable onboarding summary
|
|
42
|
+
- Generate ONBOARD.md
|
|
43
|
+
- Generate an execution flow diagram
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
```bash
|
|
47
|
+
gnost summary [path]
|
|
48
|
+
gnost stats [path]
|
|
49
|
+
gnost folders [path]
|
|
50
|
+
gnost files [path] --top 10
|
|
51
|
+
gnost onboard [path]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Key Commands
|
|
55
|
+
- `summary` Show a high-level project summary
|
|
56
|
+
- `stats` Show detailed language statistics
|
|
57
|
+
- `folders` Show LOC grouped by folder
|
|
58
|
+
- `files` Show largest files by LOC
|
|
59
|
+
- `onboard` Generate onboarding summary and flow diagrams
|
|
60
|
+
- `version` Display GNOST version
|
|
61
|
+
|
|
62
|
+
## Onboarding & Flow Analysis
|
|
63
|
+
- Generate onboarding documentation:
|
|
64
|
+
```bash
|
|
65
|
+
gnost onboard .
|
|
66
|
+
```
|
|
67
|
+
- Generate only a Mermaid flow diagram:
|
|
68
|
+
```bash
|
|
69
|
+
gnost onboard . --mermaid
|
|
70
|
+
```
|
|
71
|
+
This produces:
|
|
72
|
+
- ONBOARD.md — onboarding guide
|
|
73
|
+
- FLOW.mmd — pure Mermaid flow diagram
|
|
74
|
+
|
|
75
|
+
### Options
|
|
76
|
+
- `--include` Comma-separated folders to include
|
|
77
|
+
- `--exclude` Comma-separated folders to exclude
|
|
78
|
+
- `--top` Number of files to show with files
|
|
79
|
+
- `--version` Show version and exit
|
|
80
|
+
- `--help` Show help
|
|
81
|
+
|
|
82
|
+
## examples
|
|
83
|
+
```bash
|
|
84
|
+
gnost summary .
|
|
85
|
+
gnost stats .
|
|
86
|
+
gnost onboard .
|
|
87
|
+
gnost onboard . --mermaid
|
|
88
|
+
gnost files src --top 20
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Philosophy
|
|
92
|
+
GNOST is not a **static analyzer or linter**.
|
|
93
|
+
|
|
94
|
+
It focuses on:
|
|
95
|
+
- Mental model generation
|
|
96
|
+
- Execution understanding
|
|
97
|
+
- Developer onboarding
|
|
98
|
+
|
|
99
|
+
It uses **heuristic-based static analysis** to stay fast, simple, and language-agnostic.
|
|
100
|
+
|
|
101
|
+
## Roadmap
|
|
102
|
+
|
|
103
|
+
### v0.2.0 (Planned)
|
|
104
|
+
|
|
105
|
+
- Hotspot visualization in Mermaid diagrams
|
|
106
|
+
- Standalone `gnost hotspots` command
|
|
107
|
+
- Improved JavaScript / TypeScript import resolution
|
|
108
|
+
- Better framework awareness (Express, Spring MVC)
|
|
109
|
+
- Optional Tree-sitter based parsing for deeper analysis
|
|
110
|
+
- GitHub Action enhancements (PR comments, annotations)
|
|
111
|
+
|
|
112
|
+
## License
|
|
113
|
+
MIT License
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from gnost import __version__
|
|
3
|
+
from gnost.scanner.engine import scan
|
|
4
|
+
from gnost.reporters import stats, folders, files, loc_summary
|
|
5
|
+
from gnost.cli.commands.onboard import run as onboard_run
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main():
|
|
9
|
+
parser = argparse.ArgumentParser(
|
|
10
|
+
prog="gnost",
|
|
11
|
+
usage="gnost [command]",
|
|
12
|
+
description="GNOST — Code Knowledge Scanner",
|
|
13
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
14
|
+
epilog=(
|
|
15
|
+
"Command Options:\n"
|
|
16
|
+
" summary|stats|folders|files:\n"
|
|
17
|
+
" --include Comma-separated folder names to include\n"
|
|
18
|
+
" --exclude Comma-separated folder names to exclude\n"
|
|
19
|
+
" --progress Show a progress bar while scanning\n"
|
|
20
|
+
" onboard:\n"
|
|
21
|
+
" --progress Show a progress bar while onboarding\n"
|
|
22
|
+
" --mermaid Generate only Mermaid flow diagram\n"
|
|
23
|
+
" files:\n"
|
|
24
|
+
" --top Number of files to show (default: 5)\n"
|
|
25
|
+
"Use `gnost <command> --help` for full command options."
|
|
26
|
+
),
|
|
27
|
+
)
|
|
28
|
+
parser.add_argument("--version", action="version", version=f"gnost {__version__}")
|
|
29
|
+
|
|
30
|
+
sub = parser.add_subparsers(
|
|
31
|
+
dest="cmd",
|
|
32
|
+
required=True,
|
|
33
|
+
title="Available Commands",
|
|
34
|
+
metavar="command",
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
base = argparse.ArgumentParser(add_help=False)
|
|
38
|
+
base.add_argument("path", nargs="?", default=".", help="Directory to scan")
|
|
39
|
+
base.add_argument(
|
|
40
|
+
"--exclude",
|
|
41
|
+
help="Comma-separated folder names to exclude (e.g. node_modules,dist)",
|
|
42
|
+
)
|
|
43
|
+
base.add_argument(
|
|
44
|
+
"--include",
|
|
45
|
+
help="Comma-separated folder names to include (only these are scanned)",
|
|
46
|
+
)
|
|
47
|
+
base.add_argument(
|
|
48
|
+
"--progress",
|
|
49
|
+
action="store_true",
|
|
50
|
+
help="Show a progress bar while scanning",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
sub.add_parser("summary", parents=[base], help="Show a summary table")
|
|
54
|
+
sub.add_parser("stats", parents=[base], help="Show detailed stats per language")
|
|
55
|
+
sub.add_parser("folders", parents=[base], help="Show LOC grouped by folder")
|
|
56
|
+
|
|
57
|
+
files_parser = sub.add_parser(
|
|
58
|
+
"files", parents=[base], help="Show the largest files by LOC"
|
|
59
|
+
)
|
|
60
|
+
files_parser.add_argument(
|
|
61
|
+
"--top",
|
|
62
|
+
type=int,
|
|
63
|
+
default=5,
|
|
64
|
+
help="Number of files to show (default: 5)",
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
sub.add_parser("version", help="Display gnost version")
|
|
68
|
+
onboard = sub.add_parser("onboard", help="Onboard a new codebase")
|
|
69
|
+
onboard.add_argument("path", nargs="?", default=".")
|
|
70
|
+
onboard.add_argument(
|
|
71
|
+
"--mermaid",
|
|
72
|
+
action="store_true",
|
|
73
|
+
help="Generate only Mermaid flow diagram (FLOW.mmd)",
|
|
74
|
+
)
|
|
75
|
+
onboard.add_argument(
|
|
76
|
+
"--progress",
|
|
77
|
+
action="store_true",
|
|
78
|
+
help="Show a progress bar while onboarding",
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
args = parser.parse_args()
|
|
82
|
+
|
|
83
|
+
if args.cmd == "version":
|
|
84
|
+
print(f"gnost {__version__}")
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
if args.cmd == "onboard":
|
|
88
|
+
onboard_run(
|
|
89
|
+
args.path,
|
|
90
|
+
diagram_only=getattr(args, "mermaid", False),
|
|
91
|
+
progress=getattr(args, "progress", False),
|
|
92
|
+
)
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
include = args.include.split(",") if args.include else []
|
|
96
|
+
exclude = args.exclude.split(",") if args.exclude else []
|
|
97
|
+
|
|
98
|
+
data = scan(args.path, include, exclude, progress=args.progress)
|
|
99
|
+
|
|
100
|
+
if args.cmd == "stats":
|
|
101
|
+
stats.render(data)
|
|
102
|
+
elif args.cmd == "folders":
|
|
103
|
+
folders.render(data)
|
|
104
|
+
elif args.cmd == "files":
|
|
105
|
+
files.render(data, args.top)
|
|
106
|
+
else:
|
|
107
|
+
loc_summary.render(data)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
if __name__ == "__main__":
|
|
111
|
+
main()
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# gnost/cli/commands/onboard.py
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
from gnost.languages.python import PythonAdapter
|
|
6
|
+
from gnost.languages.javascript import JavaScriptAdapter
|
|
7
|
+
from gnost.languages.typescript import TypeScriptAdapter
|
|
8
|
+
from gnost.languages.java import JavaAdapter
|
|
9
|
+
from gnost.scanner.engine import ScannerEngine
|
|
10
|
+
from gnost.core.graph import DependencyGraph
|
|
11
|
+
from gnost.core.flow import FlowBuilder
|
|
12
|
+
from gnost.reporters.summary import SummaryReporter
|
|
13
|
+
from gnost.reporters.markdown import MarkdownReporter
|
|
14
|
+
from gnost.reporters.mermaid import MermaidFlowReporter
|
|
15
|
+
from gnost.utils.progress import progress_bar
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def run(path: str | None = None, diagram_only: bool = False, progress: bool = False):
|
|
19
|
+
"""
|
|
20
|
+
gnost onboard [path] [--mermaid]
|
|
21
|
+
Generates a high-level onboarding summary for a codebase.
|
|
22
|
+
"""
|
|
23
|
+
root = os.path.abspath(path or ".")
|
|
24
|
+
|
|
25
|
+
with progress_bar(enabled=progress, total=4, desc="Onboarding") as bar:
|
|
26
|
+
# -------------------------
|
|
27
|
+
# 1. Language adapters
|
|
28
|
+
# -------------------------
|
|
29
|
+
adapters = [
|
|
30
|
+
PythonAdapter(),
|
|
31
|
+
JavaScriptAdapter(),
|
|
32
|
+
TypeScriptAdapter(),
|
|
33
|
+
JavaAdapter(),
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
# -------------------------
|
|
37
|
+
# 2. Scan repository
|
|
38
|
+
# -------------------------
|
|
39
|
+
scanner = ScannerEngine(adapters=adapters)
|
|
40
|
+
scan_result = scanner.scan(root)
|
|
41
|
+
if bar is not None:
|
|
42
|
+
bar.update(1)
|
|
43
|
+
|
|
44
|
+
# -------------------------
|
|
45
|
+
# 3. Build dependency graph
|
|
46
|
+
# -------------------------
|
|
47
|
+
graph = DependencyGraph.from_scan(scan_result)
|
|
48
|
+
if bar is not None:
|
|
49
|
+
bar.update(1)
|
|
50
|
+
|
|
51
|
+
# -------------------------
|
|
52
|
+
# 4. Build execution flow
|
|
53
|
+
# -------------------------
|
|
54
|
+
flow_builder = FlowBuilder(graph=graph, scan=scan_result)
|
|
55
|
+
flow_result = flow_builder.build()
|
|
56
|
+
if bar is not None:
|
|
57
|
+
bar.update(1)
|
|
58
|
+
|
|
59
|
+
# -------------------------
|
|
60
|
+
# 5. Diagram-only mode
|
|
61
|
+
# -------------------------
|
|
62
|
+
if diagram_only:
|
|
63
|
+
diagram = MermaidFlowReporter(
|
|
64
|
+
flow=flow_result,
|
|
65
|
+
root=scan_result.root,
|
|
66
|
+
).render(markdown=False)
|
|
67
|
+
|
|
68
|
+
output_path = os.path.join(root, "FLOW.mmd")
|
|
69
|
+
with open(output_path, "w", encoding="utf-8") as f:
|
|
70
|
+
f.write(diagram + "\n")
|
|
71
|
+
|
|
72
|
+
if bar is not None:
|
|
73
|
+
bar.update(1)
|
|
74
|
+
|
|
75
|
+
print(f"Mermaid flow diagram written to {output_path}")
|
|
76
|
+
return
|
|
77
|
+
|
|
78
|
+
# -------------------------
|
|
79
|
+
# 6. Normal onboarding
|
|
80
|
+
# -------------------------
|
|
81
|
+
SummaryReporter(
|
|
82
|
+
scan=scan_result,
|
|
83
|
+
flow=flow_result,
|
|
84
|
+
graph=graph,
|
|
85
|
+
).render()
|
|
86
|
+
|
|
87
|
+
MarkdownReporter(
|
|
88
|
+
scan=scan_result,
|
|
89
|
+
flow=flow_result,
|
|
90
|
+
output_file="ONBOARD.md",
|
|
91
|
+
).write()
|
|
92
|
+
|
|
93
|
+
if bar is not None:
|
|
94
|
+
bar.update(1)
|
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
LANG_EXTENSIONS = {
|
|
2
|
+
"py": "Python",
|
|
3
|
+
"js": "JavaScript",
|
|
4
|
+
"ts": "TypeScript",
|
|
5
|
+
"java": "Java",
|
|
6
|
+
"go": "Go",
|
|
7
|
+
"cpp": "C++",
|
|
8
|
+
"c": "C",
|
|
9
|
+
"cs": "C#",
|
|
10
|
+
"rs": "Rust",
|
|
11
|
+
"php": "PHP",
|
|
12
|
+
"html": "HTML",
|
|
13
|
+
"css": "CSS",
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
LANGUAGES = {
|
|
17
|
+
"py": {"name": "Python", "comment": "#"},
|
|
18
|
+
"js": {"name": "JavaScript", "comment": "//"},
|
|
19
|
+
"ts": {"name": "TypeScript", "comment": "//"},
|
|
20
|
+
"java": {"name": "Java", "comment": "//"},
|
|
21
|
+
"c": {"name": "C", "comment": "//"},
|
|
22
|
+
"cpp": {"name": "C++", "comment": "//"},
|
|
23
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from gnost.config.languages import LANG_EXTENSIONS
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def count_loc(path: str = "."):
|
|
6
|
+
results = {}
|
|
7
|
+
file_count = {}
|
|
8
|
+
|
|
9
|
+
for root, _, files in os.walk(path):
|
|
10
|
+
for f in files:
|
|
11
|
+
ext = f.split(".")[-1].lower()
|
|
12
|
+
if ext in LANG_EXTENSIONS:
|
|
13
|
+
file_count.setdefault(ext, 0)
|
|
14
|
+
results.setdefault(ext, 0)
|
|
15
|
+
file_count[ext] += 1
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
with open(os.path.join(root, f), "r", errors="ignore") as fh:
|
|
19
|
+
results[ext] += sum(1 for _ in fh)
|
|
20
|
+
except:
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
return results, file_count
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# gnost/core/flow.py
|
|
2
|
+
|
|
3
|
+
from typing import List, Dict, Set
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from gnost.scanner.models import ScanResult
|
|
7
|
+
from gnost.languages.base import EntryPoint
|
|
8
|
+
from gnost.core.graph import DependencyGraph
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class FlowPath:
|
|
13
|
+
"""
|
|
14
|
+
Represents one execution path.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
start: str
|
|
18
|
+
path: List[str]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class FlowResult:
|
|
23
|
+
"""
|
|
24
|
+
Complete flow analysis result.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
entry_points: List[EntryPoint]
|
|
28
|
+
paths: List[FlowPath]
|
|
29
|
+
layers: Dict[str, Set[str]] # entry, core, leaf
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class FlowBuilder:
|
|
33
|
+
"""
|
|
34
|
+
Builds execution flow using:
|
|
35
|
+
- Entry points
|
|
36
|
+
- Dependency graph
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, graph: DependencyGraph, scan: ScanResult):
|
|
40
|
+
self.graph = graph
|
|
41
|
+
self.scan = scan
|
|
42
|
+
|
|
43
|
+
# -------------------------
|
|
44
|
+
# Public API
|
|
45
|
+
# -------------------------
|
|
46
|
+
|
|
47
|
+
def build(self) -> FlowResult:
|
|
48
|
+
entry_files = self._resolve_entry_files()
|
|
49
|
+
paths: List[FlowPath] = []
|
|
50
|
+
|
|
51
|
+
for entry in entry_files:
|
|
52
|
+
self._walk(
|
|
53
|
+
start=entry,
|
|
54
|
+
current=entry,
|
|
55
|
+
visited=set(),
|
|
56
|
+
path=[],
|
|
57
|
+
paths=paths,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
layers = self._classify_layers(paths)
|
|
61
|
+
|
|
62
|
+
return FlowResult(
|
|
63
|
+
entry_points=self.scan.entry_points,
|
|
64
|
+
paths=paths,
|
|
65
|
+
layers=layers,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
def _walk(
|
|
69
|
+
self,
|
|
70
|
+
start: str,
|
|
71
|
+
current: str,
|
|
72
|
+
visited: Set[str],
|
|
73
|
+
path: List[str],
|
|
74
|
+
paths: List[FlowPath],
|
|
75
|
+
):
|
|
76
|
+
if current in visited:
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
visited.add(current)
|
|
80
|
+
path.append(current)
|
|
81
|
+
|
|
82
|
+
dependencies = self.graph.dependencies_of(current)
|
|
83
|
+
|
|
84
|
+
if not dependencies:
|
|
85
|
+
paths.append(FlowPath(start=start, path=list(path)))
|
|
86
|
+
else:
|
|
87
|
+
for dep in dependencies:
|
|
88
|
+
self._walk(
|
|
89
|
+
start=start,
|
|
90
|
+
current=dep,
|
|
91
|
+
visited=set(visited),
|
|
92
|
+
path=list(path),
|
|
93
|
+
paths=paths,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
def _resolve_entry_files(self) -> List[str]:
|
|
97
|
+
"""
|
|
98
|
+
Convert EntryPoint objects into concrete files.
|
|
99
|
+
"""
|
|
100
|
+
resolved = []
|
|
101
|
+
|
|
102
|
+
for ep in self.scan.entry_points:
|
|
103
|
+
resolved.append(ep.file)
|
|
104
|
+
|
|
105
|
+
# Fallback: graph roots if no explicit entry point
|
|
106
|
+
if not resolved:
|
|
107
|
+
resolved.extend(self.graph.roots())
|
|
108
|
+
|
|
109
|
+
return list(set(resolved))
|
|
110
|
+
|
|
111
|
+
def _classify_layers(self, paths: List[FlowPath]) -> Dict[str, Set[str]]:
|
|
112
|
+
entry = set()
|
|
113
|
+
core = set()
|
|
114
|
+
leaf = set()
|
|
115
|
+
|
|
116
|
+
for flow in paths:
|
|
117
|
+
if not flow.path:
|
|
118
|
+
continue
|
|
119
|
+
|
|
120
|
+
entry.add(flow.path[0])
|
|
121
|
+
leaf.add(flow.path[-1])
|
|
122
|
+
|
|
123
|
+
for mid in flow.path[1:-1]:
|
|
124
|
+
core.add(mid)
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
"entry": entry,
|
|
128
|
+
"core": core,
|
|
129
|
+
"leaf": leaf,
|
|
130
|
+
}
|