githubtakeout 0.1.18__tar.gz → 0.1.19__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.18
3
+ Version: 0.1.19
4
4
  Summary: Backup and archive Git Repos and Gists from GitHub
5
5
  Author: Corey Goldberg
6
6
  Maintainer: Corey Goldberg
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "githubtakeout"
7
- version = "0.1.18"
7
+ version = "0.1.19"
8
8
  description = "Backup and archive Git Repos and Gists from GitHub"
9
9
  license = "MIT"
10
10
  license-files = ["LICENSE"]
@@ -73,14 +73,15 @@ respect-gitignore = true
73
73
  target-version = "py312"
74
74
 
75
75
  [tool.ruff.lint]
76
+ fixable = ["ALL"]
76
77
  select = [
77
- "D", "E", "F", "I", "PT", "RUF", "TID", "W"
78
+ "D", "E", "F", "I", "N", "FURB", "PT",
79
+ "RUF", "TID", "UP", "W"
78
80
  ]
79
81
  extend-ignore = [
80
- "D100", "D101", "D102", "D103", "D104", "D105", "D106", "D107", "D203",
81
- "D205", "D211", "D213", "D400", "D401", "RUF012"
82
+ "D100", "D101", "D102", "D103", "D105",
83
+ "D107", "D203", "D213", "RUF012"
82
84
  ]
83
- fixable = ["ALL"]
84
85
 
85
86
  [tool.ruff.format]
86
87
  docstring-code-format = true
@@ -89,6 +90,4 @@ docstring-code-line-length = 88
89
90
  [tool.refurb]
90
91
  python_version = "3.12"
91
92
  enable_all = true
92
- disable = [
93
- "FURB104", "FURB107", "FURB147", "FURB173", "FURB183", "FURB184"
94
- ]
93
+ disable = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: githubtakeout
3
- Version: 0.1.18
3
+ Version: 0.1.19
4
4
  Summary: Backup and archive Git Repos and Gists from GitHub
5
5
  Author: Corey Goldberg
6
6
  Maintainer: Corey Goldberg
@@ -15,6 +15,7 @@ import sys
15
15
  import tarfile
16
16
  import urllib
17
17
  import zipfile
18
+ from contextlib import suppress
18
19
  from pathlib import Path
19
20
  from timeit import default_timer
20
21
 
@@ -56,14 +57,13 @@ def archive(local_repo_dir, archive_format="zip", archive_basename=None):
56
57
  raise ValueError(f"{archive_format} is not a valid archive format")
57
58
  if archive_format == "none":
58
59
  return None
59
- basename = os.path.basename(local_repo_dir)
60
+ basename = local_repo_dir.stem
60
61
  extension = "tar.gz" if archive_format == "tar" else archive_format
61
62
  if archive_basename is None:
62
63
  archive_name = f"{basename}.{extension}"
63
64
  else:
64
65
  archive_name = f"{archive_basename}.{extension}"
65
- parent_dir = os.path.dirname(local_repo_dir)
66
- archive_path = os.path.join(parent_dir, archive_name)
66
+ archive_path = local_repo_dir.parent / archive_name
67
67
  logger.info(f"creating archive: {archive_path}")
68
68
  if archive_format == "tar":
69
69
  with tarfile.open(archive_path, "w:gz") as tar_archive:
@@ -72,7 +72,7 @@ def archive(local_repo_dir, archive_format="zip", archive_basename=None):
72
72
  with zipfile.ZipFile(archive_path, "w", zipfile.ZIP_DEFLATED) as zip_archive:
73
73
  repo_path = Path(local_repo_dir)
74
74
  for entry in repo_path.rglob("*"):
75
- path = os.path.join(basename, entry.relative_to(repo_path))
75
+ path = basename / entry.relative_to(repo_path)
76
76
  zip_archive.write(entry, arcname=path)
77
77
  return archive_path
78
78
 
@@ -98,12 +98,10 @@ def clone(repo_url, local_repo_dir, include_history):
98
98
  logger.error(e)
99
99
  sys.exit("error: failed cloning repo")
100
100
  finally:
101
- try:
101
+ # `UnboundLocalError` can occur if we catch a signal while cloning
102
+ with suppress(UnboundLocalError):
102
103
  # release resources
103
104
  repo.close()
104
- except UnboundLocalError:
105
- # this occurs if we catch a signal while cloning
106
- pass
107
105
 
108
106
 
109
107
  def pull(local_repo_dir):
@@ -116,12 +114,10 @@ def pull(local_repo_dir):
116
114
  logger.error(e)
117
115
  sys.exit("error: failed pulling changes in repo")
118
116
  finally:
119
- try:
117
+ # `UnboundLocalError` can occur if we catch a signal while pulling
118
+ with suppress(UnboundLocalError):
120
119
  # release resources
121
120
  repo.close()
122
- except UnboundLocalError:
123
- # this occurs if we catch a signal while pulling
124
- pass
125
121
 
126
122
 
127
123
  def get_and_archive_repo(
@@ -146,10 +142,8 @@ def get_and_archive_repo(
146
142
  needs_clone = False
147
143
  else:
148
144
  needs_clone = True
149
- try:
145
+ with suppress(FileNotFoundError):
150
146
  shutil.rmtree(local_repo_dir, onexc=remove_readonly)
151
- except FileNotFoundError:
152
- pass
153
147
  start = default_timer()
154
148
  if needs_clone:
155
149
  logger.info(f"cloning repo: {repo_name} to: {local_repo_dir}")
@@ -159,11 +153,9 @@ def get_and_archive_repo(
159
153
  pull(local_repo_dir)
160
154
  if not include_history:
161
155
  # delete the .git directory if we are not saving history
162
- try:
163
- git_dir = Path(local_repo_dir, ".git")
156
+ git_dir = Path(local_repo_dir, ".git")
157
+ with suppress(FileNotFoundError):
164
158
  shutil.rmtree(git_dir, onexc=remove_readonly)
165
- except FileNotFoundError:
166
- pass
167
159
  if description:
168
160
  # clean unsafe chars and truncate description to create a useable file name
169
161
  clean_name = re.sub(r"[/\\?%*:|\"<>\x7F\x00-\x1F]", "-", description)[:255]
@@ -174,18 +166,17 @@ def get_and_archive_repo(
174
166
  local_repo_dir, archive_format, archive_basename=archive_basename
175
167
  )
176
168
  if archive_path:
177
- size = convert_size(os.path.getsize(archive_path))
169
+ size = convert_size(archive_path.stat().st_size)
178
170
  logger.info(f"archive size: {size}")
179
171
  if not keep:
172
+ # delete repo after archive is created
180
173
  logger.info("deleting repo")
181
- try:
182
- # delete repo after archive is created
174
+ with suppress(FileNotFoundError):
183
175
  shutil.rmtree(local_repo_dir, onexc=remove_readonly)
184
- except FileNotFoundError:
185
- pass
186
176
  elapsed = default_timer() - start
187
- base_name = os.path.basename(local_repo_dir)
188
- logger.info(f"successfully backed up '{base_name}' repo in {elapsed:.3f} secs\n")
177
+ logger.info(
178
+ f"successfully backed up '{local_repo_dir.stem}' repo in {elapsed:.3f} secs\n"
179
+ )
189
180
 
190
181
 
191
182
  def get_repos(username, token, include_gists):
@@ -255,7 +246,7 @@ def run(
255
246
  list_only,
256
247
  prompt_for_token,
257
248
  ):
258
- working_dir = os.path.join(base_dir, "backups")
249
+ working_dir = base_dir / "backups"
259
250
  token = get_token(prompt_for_token)
260
251
 
261
252
  all_repos, gists = get_repos(username, token, include_gists)
@@ -271,7 +262,7 @@ def run(
271
262
  logger.info(f"creating archives in: {working_dir}\n")
272
263
  logger.info(f"found {num_repos} repos for user '{username}':\n")
273
264
  for repo in repos:
274
- local_repo_dir = os.path.join(working_dir, repo.name)
265
+ local_repo_dir = working_dir / repo.name
275
266
  url = add_creds(repo.clone_url, username, token)
276
267
  if list_only:
277
268
  logger.info(f"{username}/{repo.name}")
@@ -283,7 +274,7 @@ def run(
283
274
  logger.info("")
284
275
  logger.info(f"found {num_gists} gists for user '{username}':\n")
285
276
  for gist in gists:
286
- local_repo_dir = os.path.join(working_dir, gist.id)
277
+ local_repo_dir = working_dir / gist.id
287
278
  url = add_creds(gist.git_pull_url, username, token)
288
279
  if list_only:
289
280
  logger.info(f"{username}/{gist.id}\n - {gist.description}")
@@ -299,9 +290,6 @@ def run(
299
290
 
300
291
 
301
292
  def main():
302
- if sys.version_info < (3, 12):
303
- sys.exit("sorry, this program requires Python 3.12+")
304
-
305
293
  def formatter(prog):
306
294
  return argparse.HelpFormatter(prog, max_help_position=30)
307
295
 
@@ -309,7 +297,7 @@ def main():
309
297
  parser.add_argument("username", help="github username")
310
298
  parser.add_argument(
311
299
  "--dir",
312
- default=os.getcwd(),
300
+ default=Path.cwd(),
313
301
  help="output directory (default: .)",
314
302
  )
315
303
  parser.add_argument(
@@ -356,7 +344,7 @@ def main():
356
344
  try:
357
345
  run(
358
346
  username=args.username,
359
- base_dir=args.dir,
347
+ base_dir=Path(args.dir),
360
348
  pattern=args.pattern,
361
349
  skip_pattern=args.skip_pattern,
362
350
  archive_format=args.format,
File without changes
File without changes
File without changes