codefetch-cli 1.2.2__tar.gz → 1.2.4__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.
- {codefetch_cli-1.2.2/codefetch_cli.egg-info → codefetch_cli-1.2.4}/PKG-INFO +25 -2
- {codefetch_cli-1.2.2 → codefetch_cli-1.2.4}/README.md +24 -1
- codefetch_cli-1.2.4/codefetch/__init__.py +160 -0
- codefetch_cli-1.2.4/codefetch/cli.py +849 -0
- {codefetch_cli-1.2.2 → codefetch_cli-1.2.4/codefetch_cli.egg-info}/PKG-INFO +25 -2
- {codefetch_cli-1.2.2 → codefetch_cli-1.2.4}/pyproject.toml +1 -1
- {codefetch_cli-1.2.2 → codefetch_cli-1.2.4}/setup.py +1 -1
- codefetch_cli-1.2.2/codefetch/__init__.py +0 -5
- codefetch_cli-1.2.2/codefetch/cli.py +0 -689
- {codefetch_cli-1.2.2 → codefetch_cli-1.2.4}/LICENSE +0 -0
- {codefetch_cli-1.2.2 → codefetch_cli-1.2.4}/codefetch_cli.egg-info/SOURCES.txt +0 -0
- {codefetch_cli-1.2.2 → codefetch_cli-1.2.4}/codefetch_cli.egg-info/dependency_links.txt +0 -0
- {codefetch_cli-1.2.2 → codefetch_cli-1.2.4}/codefetch_cli.egg-info/entry_points.txt +0 -0
- {codefetch_cli-1.2.2 → codefetch_cli-1.2.4}/codefetch_cli.egg-info/top_level.txt +0 -0
- {codefetch_cli-1.2.2 → codefetch_cli-1.2.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codefetch-cli
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.4
|
|
4
4
|
Summary: Quickly fetch code files from GitHub repositories with simple commands
|
|
5
5
|
Home-page: https://github.com/InzamamulQureshi/Codefetch
|
|
6
6
|
Author: Inzamamul Qureshi
|
|
@@ -24,7 +24,7 @@ Dynamic: requires-python
|
|
|
24
24
|
|
|
25
25
|
Quickly fetch code files from GitHub repositories with simple commands.
|
|
26
26
|
|
|
27
|
-
CodeFetch is a lightweight command-line utility designed to quickly inspect, preview, and download individual source code files directly from any GitHub repository without needing to clone full repositories.
|
|
27
|
+
CodeFetch is a lightweight command-line utility and Python library designed to quickly inspect, preview, and download individual source code files directly from any GitHub repository without needing to clone full repositories.
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
@@ -35,6 +35,7 @@ CodeFetch is a lightweight command-line utility designed to quickly inspect, pre
|
|
|
35
35
|
- **Automatic Path & Case Resolution**: Automatically resolves case mismatches and finds files nested inside subdirectories.
|
|
36
36
|
- **Repository Discovery**: List all public repositories for any GitHub user with `--repos`.
|
|
37
37
|
- **Tree Exploration**: List all supported code files within a repository with `--list`.
|
|
38
|
+
- **Python Library Support**: Import and use programmatically with `import codefetch as cf`.
|
|
38
39
|
- **Optional Persistent Defaults**: Save a default repository or user with `--set-default` if you frequently work with the same repository.
|
|
39
40
|
- **Zero Runtime Dependencies**: Built using only the Python standard library with zero third-party dependencies.
|
|
40
41
|
|
|
@@ -130,6 +131,28 @@ codefetch --reset-config
|
|
|
130
131
|
|
|
131
132
|
---
|
|
132
133
|
|
|
134
|
+
## Python API Usage
|
|
135
|
+
|
|
136
|
+
You can also use CodeFetch programmatically within your Python scripts:
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
import codefetch as cf
|
|
140
|
+
|
|
141
|
+
# 1. Fetch file content as a string directly in memory
|
|
142
|
+
makefile_text = cf.get("torvalds/linux", "Makefile")
|
|
143
|
+
# Or shorthand single argument syntax:
|
|
144
|
+
readme_text = cf.get("psf/requests/README.md")
|
|
145
|
+
|
|
146
|
+
# 2. Download a file to disk
|
|
147
|
+
cf.download("torvalds/linux", "Makefile", output="linux_Makefile")
|
|
148
|
+
|
|
149
|
+
# 3. List all code files in a repository
|
|
150
|
+
files = cf.list("torvalds/linux")
|
|
151
|
+
print(f"Found {len(files)} files")
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
133
156
|
## Command Reference
|
|
134
157
|
|
|
135
158
|
| Flag | Description | Example |
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Quickly fetch code files from GitHub repositories with simple commands.
|
|
4
4
|
|
|
5
|
-
CodeFetch is a lightweight command-line utility designed to quickly inspect, preview, and download individual source code files directly from any GitHub repository without needing to clone full repositories.
|
|
5
|
+
CodeFetch is a lightweight command-line utility and Python library designed to quickly inspect, preview, and download individual source code files directly from any GitHub repository without needing to clone full repositories.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -13,6 +13,7 @@ CodeFetch is a lightweight command-line utility designed to quickly inspect, pre
|
|
|
13
13
|
- **Automatic Path & Case Resolution**: Automatically resolves case mismatches and finds files nested inside subdirectories.
|
|
14
14
|
- **Repository Discovery**: List all public repositories for any GitHub user with `--repos`.
|
|
15
15
|
- **Tree Exploration**: List all supported code files within a repository with `--list`.
|
|
16
|
+
- **Python Library Support**: Import and use programmatically with `import codefetch as cf`.
|
|
16
17
|
- **Optional Persistent Defaults**: Save a default repository or user with `--set-default` if you frequently work with the same repository.
|
|
17
18
|
- **Zero Runtime Dependencies**: Built using only the Python standard library with zero third-party dependencies.
|
|
18
19
|
|
|
@@ -108,6 +109,28 @@ codefetch --reset-config
|
|
|
108
109
|
|
|
109
110
|
---
|
|
110
111
|
|
|
112
|
+
## Python API Usage
|
|
113
|
+
|
|
114
|
+
You can also use CodeFetch programmatically within your Python scripts:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
import codefetch as cf
|
|
118
|
+
|
|
119
|
+
# 1. Fetch file content as a string directly in memory
|
|
120
|
+
makefile_text = cf.get("torvalds/linux", "Makefile")
|
|
121
|
+
# Or shorthand single argument syntax:
|
|
122
|
+
readme_text = cf.get("psf/requests/README.md")
|
|
123
|
+
|
|
124
|
+
# 2. Download a file to disk
|
|
125
|
+
cf.download("torvalds/linux", "Makefile", output="linux_Makefile")
|
|
126
|
+
|
|
127
|
+
# 3. List all code files in a repository
|
|
128
|
+
files = cf.list("torvalds/linux")
|
|
129
|
+
print(f"Found {len(files)} files")
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
111
134
|
## Command Reference
|
|
112
135
|
|
|
113
136
|
| Flag | Description | Example |
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CodeFetch - Easily preview and download code files from GitHub repositories.
|
|
3
|
+
|
|
4
|
+
Usage in Python:
|
|
5
|
+
import codefetch as cf
|
|
6
|
+
|
|
7
|
+
# 1. Fetch file content as string:
|
|
8
|
+
content = cf.get("torvalds/linux", "Makefile")
|
|
9
|
+
# or shorthand target string:
|
|
10
|
+
content = cf.get("torvalds/linux/Makefile")
|
|
11
|
+
|
|
12
|
+
# 2. Download file to local disk:
|
|
13
|
+
cf.download("torvalds/linux", "Makefile", output="linux_makefile.txt")
|
|
14
|
+
|
|
15
|
+
# 3. List available code files:
|
|
16
|
+
files = cf.list("torvalds/linux")
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
__version__ = "1.2.4"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get(target, filename=None, branch=None):
|
|
23
|
+
"""
|
|
24
|
+
Fetch and return the text content of a file from GitHub.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
target: 'owner/repo' or full path 'owner/repo/path/to/file' or full GitHub URL.
|
|
28
|
+
filename: Optional path to file in repo if target is 'owner/repo'.
|
|
29
|
+
branch: Branch name (default: None, automatically detects repo default branch).
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
str: File content.
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
FileNotFoundError: If the file does not exist in the repository.
|
|
36
|
+
ValueError: If arguments cannot be resolved into a repository and filename.
|
|
37
|
+
"""
|
|
38
|
+
import urllib.request
|
|
39
|
+
from .cli import (
|
|
40
|
+
get_default_branch,
|
|
41
|
+
check_branch_exists,
|
|
42
|
+
fetch_raw_single,
|
|
43
|
+
get_repo_tree,
|
|
44
|
+
resolve_file_in_tree,
|
|
45
|
+
parse_repo_identifier,
|
|
46
|
+
resolve_invocation,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
if filename:
|
|
50
|
+
owner, repo = parse_repo_identifier(target)
|
|
51
|
+
file_path = filename.strip("/\\")
|
|
52
|
+
else:
|
|
53
|
+
owner, repo, resolved_branch, file_path = resolve_invocation(
|
|
54
|
+
[target], None, None, branch, None, None
|
|
55
|
+
)
|
|
56
|
+
if resolved_branch:
|
|
57
|
+
branch = resolved_branch
|
|
58
|
+
|
|
59
|
+
if not owner or not repo or not file_path:
|
|
60
|
+
raise ValueError(f"Could not resolve owner, repo, and filename from target='{target}', filename='{filename}'")
|
|
61
|
+
|
|
62
|
+
target_branch = branch
|
|
63
|
+
if not target_branch:
|
|
64
|
+
target_branch = get_default_branch(owner, repo)
|
|
65
|
+
elif not check_branch_exists(owner, repo, target_branch):
|
|
66
|
+
target_branch = get_default_branch(owner, repo)
|
|
67
|
+
|
|
68
|
+
# 1. Try fast direct raw fetch
|
|
69
|
+
content = fetch_raw_single(owner, repo, target_branch, file_path)
|
|
70
|
+
if content is not None:
|
|
71
|
+
return content
|
|
72
|
+
|
|
73
|
+
# 2. Try repository tree search
|
|
74
|
+
tree_data = get_repo_tree(owner, repo, target_branch)
|
|
75
|
+
matched = resolve_file_in_tree(tree_data, file_path)
|
|
76
|
+
if matched:
|
|
77
|
+
url = f"https://raw.githubusercontent.com/{owner}/{repo}/{target_branch}/{matched}"
|
|
78
|
+
req = urllib.request.Request(url, headers={"User-Agent": "codefetch"})
|
|
79
|
+
with urllib.request.urlopen(req, timeout=15) as resp:
|
|
80
|
+
return resp.read().decode("utf-8")
|
|
81
|
+
|
|
82
|
+
raise FileNotFoundError(f"File '{file_path}' not found in {owner}/{repo} ({target_branch})")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def download(target, filename=None, output=None, branch=None):
|
|
86
|
+
"""
|
|
87
|
+
Download a file from GitHub and save it locally.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
target: 'owner/repo' or full path 'owner/repo/path/to/file'.
|
|
91
|
+
filename: Optional path to file in repo if target is 'owner/repo'.
|
|
92
|
+
output: Destination filename/path on local disk (default: original filename).
|
|
93
|
+
branch: Branch name (default: None, automatically detects repo default branch).
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
str: Path to the downloaded file.
|
|
97
|
+
"""
|
|
98
|
+
content = get(target, filename=filename, branch=branch)
|
|
99
|
+
dest_name = output
|
|
100
|
+
if not dest_name:
|
|
101
|
+
resolved_file = filename if filename else target.rsplit("/", 1)[-1]
|
|
102
|
+
dest_name = resolved_file.rsplit("/", 1)[-1]
|
|
103
|
+
|
|
104
|
+
with open(dest_name, "w", encoding="utf-8") as f:
|
|
105
|
+
f.write(content)
|
|
106
|
+
|
|
107
|
+
return dest_name
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def list(target, branch=None):
|
|
111
|
+
"""
|
|
112
|
+
List supported code files in a repository.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
target: 'owner/repo' or repository URL.
|
|
116
|
+
branch: Branch name (default: None, automatically detects repo default branch).
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
list[str]: Relative paths of code files in the repository.
|
|
120
|
+
"""
|
|
121
|
+
from .cli import (
|
|
122
|
+
parse_repo_identifier,
|
|
123
|
+
get_default_branch,
|
|
124
|
+
check_branch_exists,
|
|
125
|
+
get_repo_tree,
|
|
126
|
+
CODE_EXTENSIONS,
|
|
127
|
+
NAMED_FILES,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
owner, repo = parse_repo_identifier(target)
|
|
131
|
+
if not owner or not repo:
|
|
132
|
+
raise ValueError(f"Invalid repository identifier: '{target}'")
|
|
133
|
+
|
|
134
|
+
target_branch = branch
|
|
135
|
+
if not target_branch or not check_branch_exists(owner, repo, target_branch):
|
|
136
|
+
target_branch = get_default_branch(owner, repo)
|
|
137
|
+
|
|
138
|
+
tree_data = get_repo_tree(owner, repo, target_branch)
|
|
139
|
+
files = []
|
|
140
|
+
for item in tree_data.get("tree", []):
|
|
141
|
+
if item.get("type") != "blob":
|
|
142
|
+
continue
|
|
143
|
+
path = item.get("path", "")
|
|
144
|
+
base_name = path.rsplit("/", 1)[-1].lower()
|
|
145
|
+
suffix = ""
|
|
146
|
+
if "." in base_name:
|
|
147
|
+
suffix = "." + base_name.rsplit(".", 1)[-1]
|
|
148
|
+
if suffix in CODE_EXTENSIONS or base_name in NAMED_FILES:
|
|
149
|
+
files.append(path)
|
|
150
|
+
|
|
151
|
+
files.sort(key=str.lower)
|
|
152
|
+
return files
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
__all__ = [
|
|
156
|
+
"__version__",
|
|
157
|
+
"get",
|
|
158
|
+
"download",
|
|
159
|
+
"list",
|
|
160
|
+
]
|