gitpush-tool 0.1.4__tar.gz → 0.2.1__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,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitpush-tool
3
- Version: 0.1.4
3
+ Version: 0.2.1
4
4
  Summary: A CLI tool to simplify Git push operations with intelligent defaults and options.
5
- Home-page: https://github.com/yourusername/gitpush_tool
5
+ Home-page: https://github.com/inevitablegs/gitpush
6
6
  Author: Ganesh Sonawane
7
- Author-email: sonawaneganu3101@example.com
7
+ Author-email: sonawaneganu3101@gmail.com
8
8
  License: MIT
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: License :: OSI Approved :: MIT License
@@ -12,6 +12,7 @@ Classifier: Operating System :: OS Independent
12
12
  Requires-Python: >=3.6
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
+ Requires-Dist: requests>=2.25.0
15
16
  Dynamic: author
16
17
  Dynamic: author-email
17
18
  Dynamic: classifier
@@ -20,6 +21,7 @@ Dynamic: description-content-type
20
21
  Dynamic: home-page
21
22
  Dynamic: license
22
23
  Dynamic: license-file
24
+ Dynamic: requires-dist
23
25
  Dynamic: requires-python
24
26
  Dynamic: summary
25
27
 
@@ -0,0 +1 @@
1
+ __version__ = "0.2.1"
@@ -0,0 +1,211 @@
1
+ #!/usr/bin/env python3
2
+ import os
3
+ import argparse
4
+ import sys
5
+ import subprocess
6
+ from datetime import datetime
7
+ import requests
8
+
9
+ def check_gh_installed():
10
+ """Check if GitHub CLI is installed"""
11
+ try:
12
+ subprocess.run(["gh", "--version"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
13
+ return True
14
+ except:
15
+ return False
16
+
17
+ def gh_authenticated():
18
+ """Check if user is authenticated with GitHub CLI"""
19
+ try:
20
+ result = subprocess.run(["gh", "auth", "status"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
21
+ return result.returncode == 0
22
+ except:
23
+ return False
24
+
25
+ def authenticate_with_gh():
26
+ """Authenticate user with GitHub CLI"""
27
+ print("\n🔑 GitHub authentication required")
28
+ print("We'll use the GitHub CLI (gh) for authentication")
29
+ print("This will open your browser for secure login")
30
+
31
+ try:
32
+ subprocess.run(["gh", "auth", "login", "--web", "-h", "github.com"], check=True)
33
+ return True
34
+ except subprocess.CalledProcessError:
35
+ print("❌ Authentication failed")
36
+ return False
37
+ except FileNotFoundError:
38
+ print("❌ GitHub CLI not found")
39
+ return False
40
+
41
+ def create_with_gh_cli(repo_name, private=False, description="", commit_message="Initial commit"):
42
+ """Create and push to new repository using GitHub CLI"""
43
+ try:
44
+ private_flag = "--private" if private else "--public"
45
+ cmd = [
46
+ "gh", "repo", "create", repo_name,
47
+ private_flag,
48
+ "--source=.",
49
+ "--remote=origin",
50
+ "--push"
51
+ ]
52
+
53
+ if description:
54
+ cmd.extend(["--description", description])
55
+
56
+ # Run the command
57
+ result = subprocess.run(cmd, check=True)
58
+
59
+ if result.returncode == 0:
60
+ # Get the repo URL
61
+ url_result = subprocess.run(
62
+ ["gh", "repo", "view", "--json", "url", "--jq", ".url"],
63
+ stdout=subprocess.PIPE,
64
+ text=True,
65
+ check=True
66
+ )
67
+ repo_url = url_result.stdout.strip()
68
+ print(f"✅ Successfully created repository: {repo_url}")
69
+ return True
70
+ return False
71
+ except subprocess.CalledProcessError as e:
72
+ print(f"❌ Failed to create repository: {e.stderr}")
73
+ return False
74
+
75
+ def initialize_repository(remote_url=None):
76
+ """Initialize git repository with sensible defaults"""
77
+ if not os.path.exists(".git"):
78
+ print("🛠 Initializing git repository")
79
+ subprocess.run(["git", "init"], check=True)
80
+ subprocess.run(["git", "branch", "-M", "main"], check=True)
81
+
82
+ if remote_url:
83
+ subprocess.run(["git", "remote", "add", "origin", remote_url], check=True)
84
+
85
+ # Create basic .gitignore if doesn't exist
86
+ if not os.path.exists(".gitignore"):
87
+ with open(".gitignore", "w") as f:
88
+ f.write("""# Python
89
+ __pycache__/
90
+ *.py[cod]
91
+ *.so
92
+ .Python
93
+ env/
94
+ venv/
95
+ .env
96
+
97
+ # IDE
98
+ .vscode/
99
+ .idea/
100
+ *.swp
101
+ *.swo
102
+
103
+ # System
104
+ .DS_Store
105
+ Thumbs.db
106
+
107
+ # Project specific
108
+ *.log
109
+ *.tmp
110
+ *.bak
111
+ """)
112
+ print("📁 Created .gitignore file")
113
+
114
+ def check_for_updates():
115
+ """Check for newer versions on PyPI"""
116
+ try:
117
+ current_version = "0.2.1" # Should match your setup.py
118
+ response = requests.get("https://pypi.org/pypi/gitpush-tool/json", timeout=2)
119
+ latest_version = response.json()["info"]["version"]
120
+ if latest_version != current_version:
121
+ print(f"ℹ️ New version available: {latest_version} (you have {current_version})")
122
+ print(" Run 'pip install --upgrade gitpush-tool' to update")
123
+ except:
124
+ pass
125
+
126
+ def run():
127
+ parser = argparse.ArgumentParser(
128
+ description="🚀 Supercharged Git push tool with GitHub repo creation",
129
+ formatter_class=argparse.RawDescriptionHelpFormatter,
130
+ epilog="""Examples:
131
+ Basic push: gitpush_tool "Commit message"
132
+ Create new repo: gitpush_tool "Initial commit" --new-repo project-name
133
+ Private repository: gitpush_tool --new-repo private-project --private
134
+ Force push: gitpush_tool "Fix critical bug" --force
135
+ Push specific branch: gitpush_tool "Update feature" feature-branch upstream
136
+ """
137
+ )
138
+ parser.add_argument("commit", nargs="?", help="Commit message")
139
+ parser.add_argument("branch", nargs="?", default="main", help="Branch name (default: main)")
140
+ parser.add_argument("remote", nargs="?", default="origin", help="Remote name (default: origin)")
141
+ parser.add_argument("--force", action="store_true", help="Force push with --force-with-lease")
142
+ parser.add_argument("--tags", action="store_true", help="Push tags")
143
+ parser.add_argument("--init", action="store_true", help="Initialize git repo")
144
+ parser.add_argument("--new-repo", metavar="NAME", help="Create new GitHub repository")
145
+ parser.add_argument("--private", action="store_true", help="Make repository private")
146
+ parser.add_argument("--description", help="Repository description")
147
+
148
+ args = parser.parse_args()
149
+
150
+ if args.new_repo:
151
+ print(f"🆕 Creating repository: {args.new_repo}")
152
+
153
+ # Check if GitHub CLI is installed
154
+ if not check_gh_installed():
155
+ print("❌ GitHub CLI (gh) is not installed")
156
+ print("Please install it first:")
157
+ print(" Mac (Homebrew): brew install gh")
158
+ print(" Windows (Winget): winget install --id GitHub.cli")
159
+ print(" Linux: See https://github.com/cli/cli#installation")
160
+ sys.exit(1)
161
+
162
+ # Check if authenticated
163
+ if not gh_authenticated():
164
+ if not authenticate_with_gh():
165
+ sys.exit(1)
166
+
167
+ # Create repository
168
+ if not create_with_gh_cli(
169
+ args.new_repo,
170
+ private=args.private,
171
+ description=args.description or "",
172
+ commit_message=args.commit or "Initial commit"
173
+ ):
174
+ sys.exit(1)
175
+
176
+ if args.init:
177
+ initialize_repository()
178
+
179
+ # Stage all changes
180
+ subprocess.run(["git", "add", "."], check=True)
181
+
182
+ if args.commit:
183
+ print(f"📦 Committing: '{args.commit}'")
184
+ try:
185
+ subprocess.run(['git', 'commit', '-m', args.commit], check=True)
186
+ except subprocess.CalledProcessError:
187
+ print("❌ Commit failed")
188
+ sys.exit(1)
189
+ else:
190
+ print("⚠️ Skipping commit (no message provided)")
191
+
192
+ # Build push command
193
+ push_cmd = ["git", "push"]
194
+ if args.force:
195
+ push_cmd.append("--force-with-lease")
196
+ if args.tags:
197
+ push_cmd.append("--tags")
198
+ if args.remote and args.branch:
199
+ push_cmd.extend([args.remote, args.branch])
200
+
201
+ print(f"🚀 Executing: {' '.join(push_cmd)}")
202
+ try:
203
+ subprocess.run(push_cmd, check=True)
204
+ print("✅ Successfully pushed changes")
205
+ except subprocess.CalledProcessError:
206
+ print("❌ Push failed")
207
+ sys.exit(1)
208
+
209
+ if __name__ == "__main__":
210
+ check_for_updates()
211
+ run()
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitpush-tool
3
- Version: 0.1.4
3
+ Version: 0.2.1
4
4
  Summary: A CLI tool to simplify Git push operations with intelligent defaults and options.
5
- Home-page: https://github.com/yourusername/gitpush_tool
5
+ Home-page: https://github.com/inevitablegs/gitpush
6
6
  Author: Ganesh Sonawane
7
- Author-email: sonawaneganu3101@example.com
7
+ Author-email: sonawaneganu3101@gmail.com
8
8
  License: MIT
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: License :: OSI Approved :: MIT License
@@ -12,6 +12,7 @@ Classifier: Operating System :: OS Independent
12
12
  Requires-Python: >=3.6
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
+ Requires-Dist: requests>=2.25.0
15
16
  Dynamic: author
16
17
  Dynamic: author-email
17
18
  Dynamic: classifier
@@ -20,6 +21,7 @@ Dynamic: description-content-type
20
21
  Dynamic: home-page
21
22
  Dynamic: license
22
23
  Dynamic: license-file
24
+ Dynamic: requires-dist
23
25
  Dynamic: requires-python
24
26
  Dynamic: summary
25
27
 
@@ -9,4 +9,5 @@ gitpush_tool.egg-info/PKG-INFO
9
9
  gitpush_tool.egg-info/SOURCES.txt
10
10
  gitpush_tool.egg-info/dependency_links.txt
11
11
  gitpush_tool.egg-info/entry_points.txt
12
+ gitpush_tool.egg-info/requires.txt
12
13
  gitpush_tool.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ requests>=2.25.0
@@ -3,20 +3,22 @@ from pathlib import Path
3
3
 
4
4
  setup(
5
5
  name="gitpush-tool",
6
- version="0.1.4",
6
+ version="0.2.1",
7
7
  packages=find_packages(),
8
- install_requires=[],
8
+ install_requires=[
9
+ 'requests>=2.25.0',
10
+ ],
9
11
  entry_points={
10
12
  "console_scripts": [
11
13
  "gitpush_tool=gitpush_tool.cli:run"
12
14
  ],
13
15
  },
14
16
  author="Ganesh Sonawane",
15
- author_email="sonawaneganu3101@example.com",
17
+ author_email="sonawaneganu3101@gmail.com",
16
18
  description="A CLI tool to simplify Git push operations with intelligent defaults and options.",
17
19
  long_description=Path("README.md").read_text(encoding="utf-8"),
18
20
  long_description_content_type="text/markdown",
19
- url="https://github.com/yourusername/gitpush_tool",
21
+ url="https://github.com/inevitablegs/gitpush",
20
22
  license="MIT",
21
23
  classifiers=[
22
24
  "Programming Language :: Python :: 3",
@@ -1 +0,0 @@
1
- __version__ = "0.1.4"
@@ -1,166 +0,0 @@
1
- import os
2
- import argparse
3
- import sys
4
- import requests
5
- from getpass import getpass
6
- import json
7
-
8
- def get_github_token():
9
- """Get GitHub token from various sources with priority order"""
10
- # 1. Check environment variable
11
- token = os.getenv("GITHUB_TOKEN")
12
-
13
- # 2. Check token file
14
- if not token:
15
- token_path = os.path.join(os.path.dirname(__file__), '..', 'token')
16
- if os.path.exists(token_path):
17
- with open(token_path, 'r') as f:
18
- token = f.read().strip()
19
-
20
- # 3. Prompt user if still not found
21
- if not token:
22
- print("\n🔑 GitHub personal access token is required to create repositories.")
23
- print("Create one at: https://github.com/settings/tokens (with 'repo' scope)")
24
- token = getpass("Enter your GitHub token: ")
25
-
26
- return token
27
-
28
- def create_github_repo(repo_name, private=False, description=""):
29
- """Create a new GitHub repository using the GitHub API"""
30
- token = get_github_token()
31
-
32
- if not token:
33
- print("❌ GitHub token is required to create a repository")
34
- return None
35
-
36
- headers = {
37
- "Authorization": f"token {token}",
38
- "Accept": "application/vnd.github+json",
39
- "X-GitHub-Api-Version": "2022-11-28"
40
- }
41
-
42
- data = {
43
- "name": repo_name,
44
- "description": description,
45
- "private": private,
46
- "auto_init": False
47
- }
48
-
49
- try:
50
- response = requests.post(
51
- "https://api.github.com/user/repos",
52
- headers=headers,
53
- json=data
54
- )
55
-
56
- # Detailed error handling
57
- if response.status_code == 401:
58
- print("❌ Authentication failed. Invalid or expired token.")
59
- print("Please create a new token with 'repo' scope at:")
60
- print("https://github.com/settings/tokens")
61
- return None
62
-
63
- elif response.status_code == 403:
64
- print("❌ Permission denied (403 Forbidden). Possible reasons:")
65
- print("- Token doesn't have 'repo' scope")
66
- print("- Token is restricted to specific repositories")
67
- print("- GitHub API rate limit exceeded")
68
-
69
- # Try to get rate limit info
70
- try:
71
- limits = requests.get(
72
- "https://api.github.com/rate_limit",
73
- headers=headers
74
- ).json()
75
- remaining = limits['resources']['core']['remaining']
76
- reset_time = limits['resources']['core']['reset']
77
- print(f"⏳ API calls remaining: {remaining}")
78
- print(f"🔄 Rate limit resets at: {reset_time}")
79
- except:
80
- pass
81
-
82
- return None
83
-
84
- elif response.status_code == 422:
85
- error_data = response.json()
86
- if 'errors' in error_data:
87
- for error in error_data['errors']:
88
- if error.get('field') == 'name' and 'already exists' in error.get('message', ''):
89
- print(f"❌ Repository '{repo_name}' already exists")
90
- return None
91
- print(f"❌ Validation error: {error_data.get('message', 'Unknown error')}")
92
- return None
93
-
94
- elif response.status_code != 201:
95
- print(f"❌ Failed to create repository (HTTP {response.status_code}): {response.text}")
96
- return None
97
-
98
- repo_url = response.json()["html_url"]
99
- print(f"✅ Successfully created repository: {repo_url}")
100
- return repo_url
101
-
102
- except requests.exceptions.RequestException as e:
103
- print(f"❌ Failed to create repository: {str(e)}")
104
- if "Max retries exceeded" in str(e):
105
- print("⚠️ Network connection problem detected")
106
- return None
107
-
108
- def run():
109
- parser = argparse.ArgumentParser(
110
- description="📦 CLI tool to automate git operations and GitHub repository creation"
111
- )
112
- parser.add_argument("commit", nargs="?", help="Commit message")
113
- parser.add_argument("branch", nargs="?", default="main", help="Branch name (default: main)")
114
- parser.add_argument("remote", nargs="?", default="origin", help="Remote name (default: origin)")
115
- parser.add_argument("--force", action="store_true", help="Force push with --force-with-lease")
116
- parser.add_argument("--tags", action="store_true", help="Push tags")
117
- parser.add_argument("--init", action="store_true", help="Initialize git repo")
118
- parser.add_argument("--new-repo", metavar="NAME", help="Create new GitHub repository")
119
- parser.add_argument("--private", action="store_true", help="Make repository private")
120
- parser.add_argument("--description", help="Repository description")
121
-
122
- args = parser.parse_args()
123
-
124
- if args.new_repo:
125
- print(f"🆕 Creating repository: {args.new_repo}")
126
- repo_url = create_github_repo(
127
- args.new_repo,
128
- private=args.private,
129
- description=args.description or ""
130
- )
131
-
132
- if not repo_url:
133
- sys.exit(1)
134
-
135
- # Initialize git if needed
136
- if not os.path.exists(".git"):
137
- args.init = True
138
-
139
- # Set remote
140
- os.system(f"git remote add {args.remote} {repo_url}")
141
-
142
- if args.init:
143
- print("🛠 Initializing git repository")
144
- os.system("git init")
145
-
146
- os.system("git add .")
147
-
148
- if args.commit:
149
- print(f"📦 Committing: '{args.commit}'")
150
- os.system(f'git commit -m "{args.commit}"')
151
- else:
152
- print("⚠️ Skipping commit (no message provided)")
153
-
154
- push_cmd = "git push"
155
- if args.force:
156
- push_cmd += " --force-with-lease"
157
- if args.tags:
158
- push_cmd += " --tags"
159
- if args.remote and args.branch:
160
- push_cmd += f" {args.remote} {args.branch}"
161
-
162
- print(f"🚀 Executing: {push_cmd}")
163
- os.system(push_cmd)
164
-
165
- if __name__ == "__main__":
166
- run()
File without changes
File without changes
File without changes
File without changes