codefetch-cli 1.2.4__tar.gz → 1.2.5__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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codefetch-cli
3
- Version: 1.2.4
3
+ Version: 1.2.5
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
@@ -35,6 +35,7 @@ CodeFetch is a lightweight command-line utility and Python library designed to q
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
+ - **Self-Updating**: Keep CodeFetch updated to the latest PyPI release with `codefetch --update`.
38
39
  - **Python Library Support**: Import and use programmatically with `import codefetch as cf`.
39
40
  - **Optional Persistent Defaults**: Save a default repository or user with `--set-default` if you frequently work with the same repository.
40
41
  - **Zero Runtime Dependencies**: Built using only the Python standard library with zero third-party dependencies.
@@ -129,6 +130,13 @@ codefetch --config
129
130
  codefetch --reset-config
130
131
  ```
131
132
 
133
+ ### 5. Self-Updating
134
+
135
+ ```bash
136
+ # Update CodeFetch to the latest version published on PyPI
137
+ codefetch --update
138
+ ```
139
+
132
140
  ---
133
141
 
134
142
  ## Python API Usage
@@ -163,11 +171,12 @@ print(f"Found {len(files)} files")
163
171
  | `-R`, `--repos` | List public repositories for a user | `codefetch -R -u username` |
164
172
  | `-r`, `--repo` | Specify repository name or URL | `codefetch -r repo main.py` |
165
173
  | `-u`, `--user` | Specify GitHub username or organization | `codefetch -u username -r repo main.py` |
166
- | `-b`, `--branch` | Branch name (default: `main`) | `codefetch -b master owner/repo Makefile` |
174
+ | `-b`, `--branch` | Branch name (default: repo default branch) | `codefetch -b master owner/repo Makefile` |
167
175
  | `--set-default` | Set persistent default repository | `codefetch --set-default owner/repo` |
168
176
  | `--set-default-user` | Set persistent default user | `codefetch --set-default-user username` |
169
177
  | `--config` | Display active configuration | `codefetch --config` |
170
178
  | `--reset-config` | Reset configuration back to defaults | `codefetch --reset-config` |
179
+ | `-U`, `--update` | Update CodeFetch to latest PyPI version | `codefetch --update` |
171
180
  | `-v`, `--version` | Display version information | `codefetch --version` |
172
181
  | `-h`, `--help` | Display help and usage message | `codefetch --help` |
173
182
 
@@ -13,6 +13,7 @@ CodeFetch is a lightweight command-line utility and Python library designed to q
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
+ - **Self-Updating**: Keep CodeFetch updated to the latest PyPI release with `codefetch --update`.
16
17
  - **Python Library Support**: Import and use programmatically with `import codefetch as cf`.
17
18
  - **Optional Persistent Defaults**: Save a default repository or user with `--set-default` if you frequently work with the same repository.
18
19
  - **Zero Runtime Dependencies**: Built using only the Python standard library with zero third-party dependencies.
@@ -107,6 +108,13 @@ codefetch --config
107
108
  codefetch --reset-config
108
109
  ```
109
110
 
111
+ ### 5. Self-Updating
112
+
113
+ ```bash
114
+ # Update CodeFetch to the latest version published on PyPI
115
+ codefetch --update
116
+ ```
117
+
110
118
  ---
111
119
 
112
120
  ## Python API Usage
@@ -141,11 +149,12 @@ print(f"Found {len(files)} files")
141
149
  | `-R`, `--repos` | List public repositories for a user | `codefetch -R -u username` |
142
150
  | `-r`, `--repo` | Specify repository name or URL | `codefetch -r repo main.py` |
143
151
  | `-u`, `--user` | Specify GitHub username or organization | `codefetch -u username -r repo main.py` |
144
- | `-b`, `--branch` | Branch name (default: `main`) | `codefetch -b master owner/repo Makefile` |
152
+ | `-b`, `--branch` | Branch name (default: repo default branch) | `codefetch -b master owner/repo Makefile` |
145
153
  | `--set-default` | Set persistent default repository | `codefetch --set-default owner/repo` |
146
154
  | `--set-default-user` | Set persistent default user | `codefetch --set-default-user username` |
147
155
  | `--config` | Display active configuration | `codefetch --config` |
148
156
  | `--reset-config` | Reset configuration back to defaults | `codefetch --reset-config` |
157
+ | `-U`, `--update` | Update CodeFetch to latest PyPI version | `codefetch --update` |
149
158
  | `-v`, `--version` | Display version information | `codefetch --version` |
150
159
  | `-h`, `--help` | Display help and usage message | `codefetch --help` |
151
160
 
@@ -16,7 +16,7 @@ Usage in Python:
16
16
  files = cf.list("torvalds/linux")
17
17
  """
18
18
 
19
- __version__ = "1.2.4"
19
+ __version__ = "1.2.5"
20
20
 
21
21
 
22
22
  def get(target, filename=None, branch=None):
@@ -7,6 +7,7 @@ import argparse
7
7
  import json
8
8
  import os
9
9
  import re
10
+ import subprocess
10
11
  import sys
11
12
  import urllib.error
12
13
  import urllib.request
@@ -14,11 +15,10 @@ from pathlib import Path
14
15
 
15
16
  DEFAULT_OWNER = None
16
17
  DEFAULT_REPO = None
17
- DEFAULT_BRANCH = None
18
18
 
19
19
  CONFIG_FILE = Path.home() / ".codefetch.json"
20
20
 
21
- __version__ = "1.2.4"
21
+ __version__ = "1.2.5"
22
22
 
23
23
  # Supported code, data, and config extensions
24
24
  CODE_EXTENSIONS = {
@@ -62,6 +62,7 @@ USAGE:
62
62
  codefetch -s <owner>/<repo> <filename> Preview file in terminal without saving
63
63
  codefetch -l <owner>/<repo> List all code files in a repository
64
64
  codefetch -R <username> List public repositories for a user
65
+ codefetch --update Update CodeFetch to the latest version
65
66
 
66
67
  POPULAR EXAMPLES:
67
68
  # Download from any repository:
@@ -98,6 +99,7 @@ FLAGS & OPTIONS:
98
99
  --set-default-user <user> Save default user/organization
99
100
  --config Show current saved configuration
100
101
  --reset-config Reset configuration back to defaults
102
+ -U, --update Update CodeFetch to the latest version from PyPI
101
103
  -v, --version Show version number
102
104
  -h, --help Show this help message
103
105
  """
@@ -122,7 +124,7 @@ def load_config():
122
124
 
123
125
 
124
126
  def save_config(owner=None, repo=None):
125
- """Save user configuration to ~/.codefetch.json (no branch saved in config)."""
127
+ """Save user configuration to ~/.codefetch.json."""
126
128
  cfg = load_config()
127
129
  if owner is not None:
128
130
  cfg["owner"] = owner
@@ -478,7 +480,6 @@ def fetch_file(filename, owner=None, repo=None, branch=None,
478
480
 
479
481
  # Case A: Branch parameter was explicitly entered by the user
480
482
  if branch:
481
- # First, check if the specified branch exists
482
483
  branch_exists = check_branch_exists(owner, repo, branch)
483
484
 
484
485
  if not branch_exists:
@@ -490,7 +491,6 @@ def fetch_file(filename, owner=None, repo=None, branch=None,
490
491
  print(f"Available branches in {owner}/{repo}: {', '.join(shown)}{extra}")
491
492
  print(f"Trying default branch '{default_branch}'...")
492
493
 
493
- # Fall back to default branch
494
494
  actual_branch = default_branch
495
495
  try:
496
496
  content = fetch_raw_single(owner, repo, default_branch, clean_filename)
@@ -501,7 +501,6 @@ def fetch_file(filename, owner=None, repo=None, branch=None,
501
501
  pass
502
502
 
503
503
  if content is None:
504
- # Try tree on default branch
505
504
  try:
506
505
  tree_data = get_repo_tree(owner, repo, default_branch)
507
506
  matched = resolve_file_in_tree(tree_data, clean_filename)
@@ -519,7 +518,6 @@ def fetch_file(filename, owner=None, repo=None, branch=None,
519
518
  return
520
519
 
521
520
  else:
522
- # The specified branch exists! First try direct fetch from it
523
521
  actual_branch = branch
524
522
  try:
525
523
  content = fetch_raw_single(owner, repo, branch, clean_filename)
@@ -530,7 +528,6 @@ def fetch_file(filename, owner=None, repo=None, branch=None,
530
528
  pass
531
529
 
532
530
  if content is None:
533
- # Direct raw 404ed, search tree of the specified branch
534
531
  try:
535
532
  tree_data = get_repo_tree(owner, repo, branch)
536
533
  matched = resolve_file_in_tree(tree_data, clean_filename)
@@ -542,7 +539,6 @@ def fetch_file(filename, owner=None, repo=None, branch=None,
542
539
  except Exception:
543
540
  pass
544
541
 
545
- # If file not in specified branch, check default branch as well
546
542
  if content is None and branch.lower() != default_branch.lower():
547
543
  print(f"Notice: File '{clean_filename}' not found on branch '{branch}'.")
548
544
  available_branches = get_repo_branches(owner, repo)
@@ -593,7 +589,6 @@ def fetch_file(filename, owner=None, repo=None, branch=None,
593
589
  return
594
590
 
595
591
  if content is None:
596
- # Tree search on default branch
597
592
  try:
598
593
  tree_data = get_repo_tree(owner, repo, default_branch)
599
594
  matched = resolve_file_in_tree(tree_data, clean_filename)
@@ -603,7 +598,6 @@ def fetch_file(filename, owner=None, repo=None, branch=None,
603
598
  if resolved_path != clean_filename:
604
599
  print(f"(Resolved '{clean_filename}' -> '{resolved_path}')")
605
600
  else:
606
- # Check other public repositories for the same user
607
601
  other_repo, other_match = find_file_in_other_repos(owner, repo, clean_filename)
608
602
  if other_repo:
609
603
  print(f"File not found: '{clean_filename}' in {owner}/{repo} ({default_branch}).")
@@ -639,6 +633,56 @@ def fetch_file(filename, owner=None, repo=None, branch=None,
639
633
  print(f"Error saving file '{out_name}': {e}")
640
634
 
641
635
 
636
+ def parse_version_tuple(v_str):
637
+ """Parse version string like '1.2.5' into a comparable tuple of integers."""
638
+ try:
639
+ return tuple(int(x) for x in re.findall(r"\d+", v_str))
640
+ except Exception:
641
+ return (0,)
642
+
643
+
644
+ def update_codefetch():
645
+ """Update codefetch-cli to the latest version from PyPI."""
646
+ print("Checking for updates from PyPI...")
647
+ package_name = "codefetch-cli"
648
+ latest_version = None
649
+
650
+ try:
651
+ url = f"https://pypi.org/pypi/{package_name}/json"
652
+ req = urllib.request.Request(url, headers={"User-Agent": "codefetch"})
653
+ with urllib.request.urlopen(req, timeout=10) as resp:
654
+ data = json.loads(resp.read().decode("utf-8"))
655
+ latest_version = data.get("info", {}).get("version")
656
+ except Exception as e:
657
+ print(f"Note: Could not check PyPI metadata ({e}).")
658
+
659
+ if latest_version:
660
+ curr_tuple = parse_version_tuple(__version__)
661
+ latest_tuple = parse_version_tuple(latest_version)
662
+
663
+ if latest_tuple <= curr_tuple:
664
+ print(f"CodeFetch is already up to date (version {__version__}).")
665
+ return
666
+
667
+ print(f"Update available: v{latest_version} (current: v{__version__})")
668
+ print(f"Updating {package_name}...")
669
+ else:
670
+ print(f"Updating {package_name} to latest version...")
671
+
672
+ cmd = [sys.executable, "-m", "pip", "install", "--upgrade", package_name]
673
+ try:
674
+ result = subprocess.run(cmd)
675
+ if result.returncode == 0:
676
+ target_v = f"v{latest_version}" if latest_version else "the latest version"
677
+ print(f"\nSuccessfully updated CodeFetch to {target_v}!")
678
+ else:
679
+ print(f"\nUpdate failed (exit code {result.returncode}).")
680
+ print(f"You can manually update with: pip install --upgrade {package_name}")
681
+ except Exception as e:
682
+ print(f"\nError running update: {e}")
683
+ print(f"You can manually update with: pip install --upgrade {package_name}")
684
+
685
+
642
686
  class CodefetchParser(argparse.ArgumentParser):
643
687
  """Custom parser providing clean, intuitive help formatting."""
644
688
 
@@ -669,6 +713,7 @@ def build_parser():
669
713
  parser.add_argument("--set-default-user", type=str, help="Save default GitHub user")
670
714
  parser.add_argument("--config", action="store_true", help="Display active configuration")
671
715
  parser.add_argument("--reset-config", action="store_true", help="Reset configuration back to defaults")
716
+ parser.add_argument("-U", "--update", action="store_true", help="Update CodeFetch to the latest version")
672
717
  parser.add_argument("-v", "--version", action="version", version=f"%(prog)s {__version__}")
673
718
  parser.add_argument("-h", "--help", action="help", help="Show help message")
674
719
 
@@ -738,6 +783,11 @@ def main():
738
783
  parser = build_parser()
739
784
  args = parser.parse_args()
740
785
 
786
+ # Handle --update
787
+ if args.update:
788
+ update_codefetch()
789
+ return
790
+
741
791
  config = load_config()
742
792
  default_owner = config.get("owner", DEFAULT_OWNER)
743
793
  default_repo = config.get("repo", DEFAULT_REPO)
@@ -776,7 +826,6 @@ def main():
776
826
  print("CodeFetch Configuration:")
777
827
  print(f" Default User: {default_owner or 'None (not set)'}")
778
828
  print(f" Default Repository: {default_repo or 'None (not set)'}")
779
- print(" Default Branch: None (auto-detect repository default)")
780
829
  print(f" Config File: {CONFIG_FILE}")
781
830
  return
782
831
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codefetch-cli
3
- Version: 1.2.4
3
+ Version: 1.2.5
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
@@ -35,6 +35,7 @@ CodeFetch is a lightweight command-line utility and Python library designed to q
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
+ - **Self-Updating**: Keep CodeFetch updated to the latest PyPI release with `codefetch --update`.
38
39
  - **Python Library Support**: Import and use programmatically with `import codefetch as cf`.
39
40
  - **Optional Persistent Defaults**: Save a default repository or user with `--set-default` if you frequently work with the same repository.
40
41
  - **Zero Runtime Dependencies**: Built using only the Python standard library with zero third-party dependencies.
@@ -129,6 +130,13 @@ codefetch --config
129
130
  codefetch --reset-config
130
131
  ```
131
132
 
133
+ ### 5. Self-Updating
134
+
135
+ ```bash
136
+ # Update CodeFetch to the latest version published on PyPI
137
+ codefetch --update
138
+ ```
139
+
132
140
  ---
133
141
 
134
142
  ## Python API Usage
@@ -163,11 +171,12 @@ print(f"Found {len(files)} files")
163
171
  | `-R`, `--repos` | List public repositories for a user | `codefetch -R -u username` |
164
172
  | `-r`, `--repo` | Specify repository name or URL | `codefetch -r repo main.py` |
165
173
  | `-u`, `--user` | Specify GitHub username or organization | `codefetch -u username -r repo main.py` |
166
- | `-b`, `--branch` | Branch name (default: `main`) | `codefetch -b master owner/repo Makefile` |
174
+ | `-b`, `--branch` | Branch name (default: repo default branch) | `codefetch -b master owner/repo Makefile` |
167
175
  | `--set-default` | Set persistent default repository | `codefetch --set-default owner/repo` |
168
176
  | `--set-default-user` | Set persistent default user | `codefetch --set-default-user username` |
169
177
  | `--config` | Display active configuration | `codefetch --config` |
170
178
  | `--reset-config` | Reset configuration back to defaults | `codefetch --reset-config` |
179
+ | `-U`, `--update` | Update CodeFetch to latest PyPI version | `codefetch --update` |
171
180
  | `-v`, `--version` | Display version information | `codefetch --version` |
172
181
  | `-h`, `--help` | Display help and usage message | `codefetch --help` |
173
182
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "codefetch-cli"
7
- version = "1.2.4"
7
+ version = "1.2.5"
8
8
  description = "Quickly fetch code files from GitHub repositories with simple commands"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -7,7 +7,7 @@ long_description = readme_path.read_text(encoding="utf-8") if readme_path.exists
7
7
 
8
8
  setup(
9
9
  name="codefetch-cli",
10
- version="1.2.4",
10
+ version="1.2.5",
11
11
  description="Quickly fetch code files from GitHub repositories with simple commands",
12
12
  long_description=long_description,
13
13
  long_description_content_type="text/markdown",
File without changes
File without changes