Skip to content

Commit 1a971dc

Browse files
committed
Merge branch 'main' of github.com:epilande/codegrab
2 parents 07a26a9 + 2fe8c15 commit 1a971dc

27 files changed

Lines changed: 2816 additions & 127 deletions

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
.DS_Store
2-
32
*.log
3+
*.prof
4+
*.pprof
45
bin/
56
dist/
7+
perf_results/
8+
/grab

README.md

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ to your clipboard, ready for LLM processing.
2929
- 🌲 **Directory Tree View**: Display a tree-style view of your project structure
3030
- 🧮 **Token Estimation**: Get estimated token count for LLM context windows
3131
- 🛡️ **Secret Detection & Redaction**: Uses [gitleaks](https://github.com/gitleaks/gitleaks) to identify potential secrets and prevent sharing sensitive information
32-
- 🔗 **Dependency Resolution**: Automatically include dependencies for Go, JS/TS when using the `--deps` flag
32+
- 🔗 **Dependency Resolution**: Automatically include dependencies for Go, JS/TS, Python when using the `--deps` flag
33+
- 🌐 **Remote Git Repo Support**: Analyze remote repositories by passing Git URLs (supports GitHub, GitLab, Bitbucket, SSH, HTTPS)
3334

3435
## 📦 Installation
3536

@@ -84,9 +85,10 @@ grab [options] [directory]
8485

8586
### Arguments
8687

87-
| Argument | Description |
88-
| :---------- | :---------------------------------------------------- |
89-
| `directory` | Optional path to the project directory (default: ".") |
88+
| Argument | Description |
89+
| :---------- | :------------------------------------------------------------------------------ |
90+
| `directory` | Optional path to the project directory (default: ".") |
91+
| `git-url` | Git repository URL (GitHub, GitLab, Bitbucket, SSH, HTTPS) to clone and analyze |
9092

9193
### Options
9294

@@ -157,6 +159,24 @@ grab [options] [directory]
157159
grab -g="*.{ts,tsx}" -g="\!*.spec.{ts,tsx}"
158160
```
159161

162+
9. Analyze a remote Git repository:
163+
164+
```bash
165+
grab https://github.com/user/repo.git
166+
```
167+
168+
10. Analyze a remote repository non-interactively with dependencies:
169+
170+
```bash
171+
grab -n --deps https://github.com/user/repo.git
172+
```
173+
174+
11. Clone and analyze using SSH:
175+
176+
```bash
177+
grab git@github.com:user/repo.git
178+
```
179+
160180
## ⌨️ Keyboard Controls
161181

162182
### Navigation
@@ -210,6 +230,7 @@ CodeGrab can automatically include dependencies for selected files, making it ea
210230
- **Supported Languages**:
211231
- **Go**: Resolves relative imports and project-local module imports (if `go.mod` is present).
212232
- **JavaScript/TypeScript**: Resolves relative imports/requires for `.js`, `.jsx`, `.ts`, and `.tsx` files, including directory `index` files.
233+
- **Python**: Resolves relative imports for `.py` files within the project structure.
213234
- **Enabling**:
214235
- **Interactive Mode**: Press <kbd>D</kbd> to toggle dependency resolution on/off. A `🔗 Deps` indicator will appear in the footer when active. Files added as dependencies will be marked with `[dep]`.
215236
- **Non-Interactive Mode**: Use the `--deps` flag.
@@ -220,6 +241,19 @@ CodeGrab can automatically include dependencies for selected files, making it ea
220241

221242
![codegrab-deps](https://github.com/user-attachments/assets/db04805c-a0b0-4249-ab48-da3d7b92000c)
222243

244+
## 🌐 Git Repository Support
245+
246+
CodeGrab can directly analyze remote Git repositories without requiring manual cloning. Simply pass a Git URL as the directory argument, and CodeGrab will automatically clone the repository to a temporary directory.
247+
248+
- **Supported URL Formats**:
249+
- HTTPS: `https://github.com/user/repo.git` or `https://github.com/user/repo`
250+
- SSH: `git@github.com:user/repo.git`
251+
- SSH with protocol: `ssh://git@github.com/user/repo.git`
252+
- Supports GitHub, GitLab, Bitbucket, and other Git hosting platforms
253+
- **Efficient Cloning**: Uses shallow cloning (`--depth=1`) to only fetch the latest commit, making it fast and lightweight
254+
- **Automatic Cleanup**: Temporary directories are automatically cleaned up after processing
255+
- **Full Feature Support**: All CodeGrab features work with remote repositories (filtering, dependency resolution, secret detection, etc.)
256+
223257
## 🛡️ Secret Detection & Redaction
224258

225259
CodeGrab automatically scans the content of selected files for potential secrets using [gitleaks](https://github.com/gitleaks/gitleaks) with its default rules. This helps prevent accidental exposure of sensitive credentials like API keys, private tokens, and passwords.

cmd/grab/main.go

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/epilande/codegrab/internal/filesystem"
1515
"github.com/epilande/codegrab/internal/generator"
1616
"github.com/epilande/codegrab/internal/generator/formats"
17+
"github.com/epilande/codegrab/internal/git"
1718
"github.com/epilande/codegrab/internal/model"
1819
"github.com/epilande/codegrab/internal/ui"
1920
"github.com/epilande/codegrab/internal/ui/themes"
@@ -77,7 +78,7 @@ func main() {
7778
flag.StringVar(&formatName, "format", "markdown", formatUsage)
7879
flag.StringVar(&formatName, "f", "markdown", formatUsage+" (shorthand)")
7980

80-
flag.BoolVar(&resolveDeps, "deps", false, "Automatically include direct dependencies (Go, TS/JS)")
81+
flag.BoolVar(&resolveDeps, "deps", false, "Automatically include direct dependencies (Go, TS/JS, Python)")
8182

8283
flag.IntVar(&maxDepth, "max-depth", 1, "Maximum depth for dependency resolution (-1 for unlimited)")
8384

@@ -126,15 +127,44 @@ func main() {
126127

127128
// Use current directory if no argument is provided
128129
root := "."
130+
var cleanup func()
131+
var isGitRepo bool
132+
129133
if flag.NArg() > 0 {
130-
root = flag.Arg(0)
134+
arg := flag.Arg(0)
135+
136+
// Check if the argument is a Git URL
137+
if git.IsGitURL(arg) {
138+
fmt.Printf("🔄 Cloning repository: %s\n", arg)
139+
140+
clonedPath, cleanupFunc, err := git.CloneRepository(arg)
141+
if err != nil {
142+
log.Fatalf("Error cloning repository: %v", err)
143+
}
144+
145+
root = clonedPath
146+
cleanup = cleanupFunc
147+
isGitRepo = true
148+
149+
fmt.Printf("✅ Repository cloned to: %s\n", root)
150+
} else {
151+
root = arg
152+
}
131153
}
132154

133-
absRoot, err := filepath.Abs(root)
134-
if err != nil {
135-
log.Fatalf("Error getting absolute path for %q: %v", root, err)
155+
// Set up cleanup for Git repositories
156+
if cleanup != nil {
157+
defer cleanup()
158+
}
159+
160+
// Convert to absolute path for local directories
161+
if !isGitRepo {
162+
absRoot, err := filepath.Abs(root)
163+
if err != nil {
164+
log.Fatalf("Error getting absolute path for %q: %v", root, err)
165+
}
166+
root = absRoot
136167
}
137-
root = absRoot
138168

139169
// Validate the provided path
140170
if stat, err := os.Stat(root); err != nil {

go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
2727
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2828
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
2929
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
30-
github.com/epilande/go-devicons v0.0.0-20250430064519-26ca6d272b4c h1:ZKFmMr4EQ+6wni8gHq56tEmjMdIDySQ+zFgwXi+yCgc=
31-
github.com/epilande/go-devicons v0.0.0-20250430064519-26ca6d272b4c/go.mod h1:myBNrCUxmCh3ktYaRUMfL8epmWMBu6/yj0JFnQHYFSU=
3230
github.com/epilande/go-devicons v0.0.0-20250502062109-89b44a507be9 h1:wu8xPucxiGFKrSN24fE9VVzjthnfVqYFx33bNoRL8DU=
3331
github.com/epilande/go-devicons v0.0.0-20250502062109-89b44a507be9/go.mod h1:myBNrCUxmCh3ktYaRUMfL8epmWMBu6/yj0JFnQHYFSU=
3432
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=

0 commit comments

Comments
 (0)