githubtakeout 0.1.9__tar.gz → 0.1.10__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: githubtakeout
3
- Version: 0.1.9
3
+ Version: 0.1.10
4
4
  Summary: Archive public Git Repos and Gists from GitHub
5
5
  Author: Corey Goldberg
6
6
  Maintainer: Corey Goldberg
@@ -21,7 +21,6 @@ License-File: LICENSE
21
21
  Requires-Dist: GitPython==3.1.45
22
22
  Requires-Dist: PyGithub==2.8.1
23
23
  Requires-Dist: rich==14.1.0
24
- Requires-Dist: tenacity==9.1.2
25
24
  Dynamic: license-file
26
25
 
27
26
  # githubtakeout
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "githubtakeout"
7
- version = "0.1.9"
7
+ version = "0.1.10"
8
8
  description = "Archive public Git Repos and Gists from GitHub"
9
9
  license = "MIT"
10
10
  license-files = ["LICENSE"]
@@ -25,7 +25,6 @@ dependencies = [
25
25
  "GitPython==3.1.45",
26
26
  "PyGithub==2.8.1",
27
27
  "rich==14.1.0",
28
- "tenacity==9.1.2",
29
28
  ]
30
29
 
31
30
  [project.scripts]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: githubtakeout
3
- Version: 0.1.9
3
+ Version: 0.1.10
4
4
  Summary: Archive public Git Repos and Gists from GitHub
5
5
  Author: Corey Goldberg
6
6
  Maintainer: Corey Goldberg
@@ -21,7 +21,6 @@ License-File: LICENSE
21
21
  Requires-Dist: GitPython==3.1.45
22
22
  Requires-Dist: PyGithub==2.8.1
23
23
  Requires-Dist: rich==14.1.0
24
- Requires-Dist: tenacity==9.1.2
25
24
  Dynamic: license-file
26
25
 
27
26
  # githubtakeout
@@ -1,4 +1,3 @@
1
1
  GitPython==3.1.45
2
2
  PyGithub==2.8.1
3
3
  rich==14.1.0
4
- tenacity==9.1.2
@@ -19,7 +19,6 @@ from timeit import default_timer
19
19
 
20
20
  import git
21
21
  import github
22
- from tenacity import retry, stop_after_attempt, wait_fixed
23
22
 
24
23
  from progress import GitProgress
25
24
 
@@ -50,52 +49,6 @@ def add_creds(url, username, token):
50
49
  return new_url
51
50
 
52
51
 
53
- def clone_and_archive_repo(
54
- repo_url, local_repo_dir, archive_format, include_history, is_gist=False
55
- ):
56
- def remove_readonly(func, path, _):
57
- # This is necessary so rmtree() doesn't fail if there are any readonly
58
- # dirs/files when trying to delete. This seems to happen after cloning on
59
- # Windows. When any error occurs during deletion, we change the permissions
60
- # and and reattempt removal.
61
- #
62
- # give read permissions
63
- os.chmod(path, stat.S_IREAD)
64
- # give write permissions
65
- os.chmod(path, stat.S_IWRITE)
66
- # try again
67
- func(path)
68
-
69
- try:
70
- # delete repo if it already exists
71
- shutil.rmtree(local_repo_dir, onexc=remove_readonly)
72
- except FileNotFoundError:
73
- pass
74
- repo_name = urllib.parse.urlparse(repo_url).path.lstrip("/")
75
- logger.info(f"cloning repo: {repo_name} to {local_repo_dir}")
76
- start = default_timer()
77
- clone(repo_url, local_repo_dir, include_history)
78
- if not include_history:
79
- # delete the .git directory if we are not saving history
80
- try:
81
- git_dir = os.path.join(local_repo_dir, ".git")
82
- shutil.rmtree(git_dir, onexc=remove_readonly)
83
- except FileNotFoundError:
84
- pass
85
- archive_path = archive(local_repo_dir, archive_format, is_gist)
86
- size = convert_size(os.path.getsize(archive_path))
87
- logger.info(f"archive size: {size}")
88
- logger.info("deleting repo")
89
- try:
90
- # delete repo after archive is created
91
- shutil.rmtree(local_repo_dir, onexc=remove_readonly)
92
- except FileNotFoundError:
93
- pass
94
- elapsed = default_timer() - start
95
- base_name = os.path.basename(local_repo_dir)
96
- logger.info(f"successfully backed up '{base_name}' repo in {elapsed:.3f} secs\n")
97
-
98
-
99
52
  def archive(local_repo_dir, archive_format="zip", is_gist=False):
100
53
  if archive_format not in ARCHIVE_FORMATS:
101
54
  raise ValueError(f"{archive_format} is not a valid archive format")
@@ -119,7 +72,6 @@ def archive(local_repo_dir, archive_format="zip", is_gist=False):
119
72
  return archive_path
120
73
 
121
74
 
122
- @retry(stop=stop_after_attempt(5), wait=wait_fixed(2))
123
75
  def clone(repo_url, local_repo_dir, include_history):
124
76
  try:
125
77
  if include_history:
@@ -149,12 +101,52 @@ def clone(repo_url, local_repo_dir, include_history):
149
101
  pass
150
102
 
151
103
 
152
- @retry(stop=stop_after_attempt(5), wait=wait_fixed(2))
153
- def count_repos(repos):
154
- return repos.totalCount
104
+ def clone_and_archive_repo(
105
+ repo_url, local_repo_dir, archive_format, include_history, is_gist=False
106
+ ):
107
+ def remove_readonly(func, path, _):
108
+ # This is necessary so rmtree() doesn't fail if there are any readonly
109
+ # dirs/files when trying to delete. This seems to happen after cloning on
110
+ # Windows. When any error occurs during deletion, we change the permissions
111
+ # and and reattempt removal.
112
+ #
113
+ # give read permissions
114
+ os.chmod(path, stat.S_IREAD)
115
+ # give write permissions
116
+ os.chmod(path, stat.S_IWRITE)
117
+ # try again
118
+ func(path)
119
+
120
+ try:
121
+ # delete repo if it already exists
122
+ shutil.rmtree(local_repo_dir, onexc=remove_readonly)
123
+ except FileNotFoundError:
124
+ pass
125
+ repo_name = urllib.parse.urlparse(repo_url).path.lstrip("/")
126
+ logger.info(f"cloning repo: {repo_name} to {local_repo_dir}")
127
+ start = default_timer()
128
+ clone(repo_url, local_repo_dir, include_history)
129
+ if not include_history:
130
+ # delete the .git directory if we are not saving history
131
+ try:
132
+ git_dir = os.path.join(local_repo_dir, ".git")
133
+ shutil.rmtree(git_dir, onexc=remove_readonly)
134
+ except FileNotFoundError:
135
+ pass
136
+ archive_path = archive(local_repo_dir, archive_format, is_gist)
137
+ size = convert_size(os.path.getsize(archive_path))
138
+ logger.info(f"archive size: {size}")
139
+ logger.info("deleting repo")
140
+ try:
141
+ # delete repo after archive is created
142
+ shutil.rmtree(local_repo_dir, onexc=remove_readonly)
143
+ except FileNotFoundError:
144
+ pass
145
+ elapsed = default_timer() - start
146
+ base_name = os.path.basename(local_repo_dir)
147
+ logger.info(f"successfully backed up '{base_name}' repo in {elapsed:.3f} secs\n")
155
148
 
156
149
 
157
- @retry(stop=stop_after_attempt(5), wait=wait_fixed(2))
158
150
  def get_user(username, prompt_token):
159
151
  if prompt_token:
160
152
  token = getpass.getpass("Token:")
@@ -185,7 +177,7 @@ def get_user(username, prompt_token):
185
177
  repos = user.get_repos(affiliation="owner")
186
178
  try:
187
179
  # this just makes an API request so we can exit if unauthorized
188
- _ = count_repos(repos)
180
+ _ = repos.totalCount
189
181
  except github.GithubException as e:
190
182
  if e.data["status"] == "401":
191
183
  sys.exit(f"error: invalid auth token for user '{username}'")
@@ -206,7 +198,7 @@ def run(
206
198
  ):
207
199
  working_dir = os.path.join(base_dir, "backups")
208
200
  user, repos, gists, token = get_user(username, prompt_token)
209
- num_repos = count_repos(repos)
201
+ num_repos = repos.totalCount
210
202
  if not list_only:
211
203
  logger.info(f"creating archives in: {working_dir}\n")
212
204
  logger.info(f"found {num_repos} repos for user '{username}'\n")
@@ -218,7 +210,7 @@ def run(
218
210
  else:
219
211
  clone_and_archive_repo(url, local_repo_dir, archive_format, include_history)
220
212
  if include_gists:
221
- num_gists = count_repos(gists)
213
+ num_gists = gists.totalCount
222
214
  logger.info("")
223
215
  logger.info(f"found {num_gists} gists for user '{username}'\n")
224
216
  for gist in gists:
File without changes
File without changes
File without changes