github-archive 6.2.0__tar.gz → 6.3.0__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.
Files changed (28) hide show
  1. {github_archive-6.2.0 → github_archive-6.3.0}/PKG-INFO +2 -1
  2. {github_archive-6.2.0 → github_archive-6.3.0}/README.md +1 -0
  3. github_archive-6.3.0/github_archive/_version.py +1 -0
  4. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive/archive.py +10 -3
  5. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive/cli.py +8 -0
  6. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive/gists.py +1 -6
  7. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive/repos.py +21 -4
  8. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive.egg-info/PKG-INFO +2 -1
  9. {github_archive-6.2.0 → github_archive-6.3.0}/test/unit/conftest.py +1 -0
  10. {github_archive-6.2.0 → github_archive-6.3.0}/test/unit/test_archive.py +4 -0
  11. {github_archive-6.2.0 → github_archive-6.3.0}/test/unit/test_repos.py +32 -6
  12. github_archive-6.2.0/github_archive/_version.py +0 -1
  13. {github_archive-6.2.0 → github_archive-6.3.0}/LICENSE +0 -0
  14. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive/__init__.py +0 -0
  15. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive/constants.py +0 -0
  16. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive/logger.py +0 -0
  17. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive/py.typed +0 -0
  18. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive.egg-info/SOURCES.txt +0 -0
  19. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive.egg-info/dependency_links.txt +0 -0
  20. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive.egg-info/entry_points.txt +0 -0
  21. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive.egg-info/requires.txt +0 -0
  22. {github_archive-6.2.0 → github_archive-6.3.0}/github_archive.egg-info/top_level.txt +0 -0
  23. {github_archive-6.2.0 → github_archive-6.3.0}/pyproject.toml +0 -0
  24. {github_archive-6.2.0 → github_archive-6.3.0}/setup.cfg +0 -0
  25. {github_archive-6.2.0 → github_archive-6.3.0}/setup.py +0 -0
  26. {github_archive-6.2.0 → github_archive-6.3.0}/test/unit/__init__.py +0 -0
  27. {github_archive-6.2.0 → github_archive-6.3.0}/test/unit/test_gists.py +0 -0
  28. {github_archive-6.2.0 → github_archive-6.3.0}/test/unit/test_logger.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: github-archive
3
- Version: 6.2.0
3
+ Version: 6.3.0
4
4
  Summary: A powerful tool to concurrently clone, pull, or fork user and org repos and gists to create a GitHub archive.
5
5
  Home-page: http://github.com/justintime50/github-archive
6
6
  Author: Justintime50
@@ -85,6 +85,7 @@ Options:
85
85
  -f, --fork Pass this flag to fork git assets.
86
86
  --include INCLUDE Pass a comma separated list of repos to filter what is included in the Archive.
87
87
  --exclude EXCLUDE Pass a comma separated list of repos to filter what is excluded from the Archive.
88
+ --languages LANGUAGES Pass a comma separated list of languages to filter what is included in the Archive.
88
89
  --forks Pass this flag to include forked git assets (when cloning or pulling).
89
90
  --location LOCATION The location where you want your GitHub Archive to be stored. Default: /Users/USERNAME/github-archive
90
91
  --https Use HTTPS URLs instead of SSH.
@@ -50,6 +50,7 @@ Options:
50
50
  -f, --fork Pass this flag to fork git assets.
51
51
  --include INCLUDE Pass a comma separated list of repos to filter what is included in the Archive.
52
52
  --exclude EXCLUDE Pass a comma separated list of repos to filter what is excluded from the Archive.
53
+ --languages LANGUAGES Pass a comma separated list of languages to filter what is included in the Archive.
53
54
  --forks Pass this flag to include forked git assets (when cloning or pulling).
54
55
  --location LOCATION The location where you want your GitHub Archive to be stored. Default: /Users/USERNAME/github-archive
55
56
  --https Use HTTPS URLs instead of SSH.
@@ -0,0 +1 @@
1
+ __version__ = "6.3.0"
@@ -60,6 +60,7 @@ class GithubArchive:
60
60
  fork=False,
61
61
  include=None,
62
62
  exclude=None,
63
+ languages=None,
63
64
  forks=False,
64
65
  location=DEFAULT_LOCATION,
65
66
  use_https=False,
@@ -80,6 +81,7 @@ class GithubArchive:
80
81
  self.fork = fork
81
82
  self.include = include.lower().split(',') if include else ''
82
83
  self.exclude = exclude.lower().split(',') if exclude else ''
84
+ self.languages = languages.lower().split(',') if languages else ''
83
85
  self.forks = forks
84
86
  self.location = os.path.expanduser(location)
85
87
  self.use_https = use_https
@@ -147,7 +149,7 @@ class GithubArchive:
147
149
  _ = iterate_repos_to_archive(self, user_repos, PULL_OPERATION)
148
150
  if self.fork:
149
151
  logger.info('# Forking user repos...')
150
- iterate_repos_to_fork(user_repos)
152
+ iterate_repos_to_fork(self, user_repos)
151
153
 
152
154
  # Orgs
153
155
  if self.orgs:
@@ -167,7 +169,7 @@ class GithubArchive:
167
169
  _ = iterate_repos_to_archive(self, org_repos, PULL_OPERATION)
168
170
  if self.fork:
169
171
  logger.info('# Forking org repos...')
170
- iterate_repos_to_fork(org_repos)
172
+ iterate_repos_to_fork(self, org_repos)
171
173
 
172
174
  # Stars
173
175
  if self.stars:
@@ -187,7 +189,7 @@ class GithubArchive:
187
189
  _ = iterate_repos_to_archive(self, starred_repos, PULL_OPERATION)
188
190
  if self.fork:
189
191
  logger.info('# Forking starred repos...')
190
- iterate_repos_to_fork(starred_repos)
192
+ iterate_repos_to_fork(self, starred_repos)
191
193
 
192
194
  if failed_repo_dirs:
193
195
  logger.info('Cleaning up repos...')
@@ -261,6 +263,11 @@ class GithubArchive:
261
263
  logger=logger,
262
264
  message='The include and exclude flags are mutually exclusive. Only one can be used on each run.',
263
265
  )
266
+ elif (self.include or self.exclude) and self.languages:
267
+ log_and_raise_value_error(
268
+ logger=logger,
269
+ message='The include and exclude flags cannot be used with the languages flag.',
270
+ )
264
271
 
265
272
  def authenticated_user_in_users(self) -> bool:
266
273
  """Returns True if the authenticated user is in the list of users."""
@@ -109,6 +109,13 @@ class GithubArchiveCli:
109
109
  default=None,
110
110
  help='Pass a comma separated list of repos to filter what is excluded from the Archive.',
111
111
  )
112
+ parser.add_argument(
113
+ '--languages',
114
+ type=str,
115
+ required=False,
116
+ default=None,
117
+ help='Pass a comma separated list of languages to filter what is included in the Archive.',
118
+ )
112
119
  parser.add_argument(
113
120
  '--forks',
114
121
  action='store_true',
@@ -182,6 +189,7 @@ class GithubArchiveCli:
182
189
  fork=self.fork,
183
190
  include=self.include,
184
191
  exclude=self.exclude,
192
+ languages=self.languages,
185
193
  forks=self.forks,
186
194
  location=self.location,
187
195
  use_https=self.https,
@@ -28,9 +28,7 @@ from github_archive.constants import (
28
28
  )
29
29
 
30
30
 
31
- def iterate_gists_to_archive(
32
- github_archive: GithubArchive, gists: List[Gist.Gist], operation: str
33
- ) -> List[Optional[str]]:
31
+ def iterate_gists_to_archive(github_archive: GithubArchive, gists: List[Gist.Gist], operation: str) -> None:
34
32
  """Iterate over each gist and start a thread if it can be archived."""
35
33
  pool = ThreadPoolExecutor(github_archive.threads)
36
34
  thread_list = []
@@ -48,9 +46,6 @@ def iterate_gists_to_archive(
48
46
  )
49
47
 
50
48
  wait(thread_list, return_when=ALL_COMPLETED)
51
- failed_gists = [gist.result() for gist in thread_list if gist.result()]
52
-
53
- return failed_gists
54
49
 
55
50
 
56
51
  def view_gists(gists: List[Gist.Gist]):
@@ -42,7 +42,14 @@ def iterate_repos_to_archive(
42
42
 
43
43
  for repo in repos:
44
44
  if (
45
- (not github_archive.include and not github_archive.exclude)
45
+ (
46
+ github_archive.languages
47
+ and repo.language
48
+ and repo.language.lower() in github_archive.languages
49
+ and not github_archive.include
50
+ and not github_archive.exclude
51
+ )
52
+ or (not github_archive.languages and not github_archive.include and not github_archive.exclude)
46
53
  or (github_archive.include and repo.name in github_archive.include)
47
54
  or (github_archive.exclude and repo.name not in github_archive.exclude)
48
55
  ):
@@ -58,7 +65,7 @@ def iterate_repos_to_archive(
58
65
  )
59
66
  )
60
67
  else:
61
- logger.debug(f'{repo.name} skipped due to include/exclude filtering')
68
+ logger.debug(f'{repo.name} skipped due to filtering')
62
69
 
63
70
  wait(thread_list, return_when=ALL_COMPLETED)
64
71
  failed_repos = [repo.result() for repo in thread_list if repo.result()]
@@ -75,10 +82,20 @@ def view_repos(repos: List[Repository.Repository]):
75
82
  logger.info(repo_name)
76
83
 
77
84
 
78
- def iterate_repos_to_fork(repos: List[Repository.Repository]):
85
+ def iterate_repos_to_fork(github_archive: GithubArchive, repos: List[Repository.Repository]) -> None:
79
86
  """Iterates through a list of repos and attempts to fork them."""
87
+ pool = ThreadPoolExecutor(github_archive.threads)
88
+ thread_list = []
89
+
80
90
  for repo in repos:
81
- _fork_repo(repo)
91
+ thread_list.append(
92
+ pool.submit(
93
+ _fork_repo,
94
+ repo=repo,
95
+ )
96
+ )
97
+
98
+ wait(thread_list, return_when=ALL_COMPLETED)
82
99
 
83
100
 
84
101
  def _fork_repo(repo: Repository.Repository):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: github-archive
3
- Version: 6.2.0
3
+ Version: 6.3.0
4
4
  Summary: A powerful tool to concurrently clone, pull, or fork user and org repos and gists to create a GitHub archive.
5
5
  Home-page: http://github.com/justintime50/github-archive
6
6
  Author: Justintime50
@@ -85,6 +85,7 @@ Options:
85
85
  -f, --fork Pass this flag to fork git assets.
86
86
  --include INCLUDE Pass a comma separated list of repos to filter what is included in the Archive.
87
87
  --exclude EXCLUDE Pass a comma separated list of repos to filter what is excluded from the Archive.
88
+ --languages LANGUAGES Pass a comma separated list of languages to filter what is included in the Archive.
88
89
  --forks Pass this flag to include forked git assets (when cloning or pulling).
89
90
  --location LOCATION The location where you want your GitHub Archive to be stored. Default: /Users/USERNAME/github-archive
90
91
  --https Use HTTPS URLs instead of SSH.
@@ -15,5 +15,6 @@ def mock_git_asset():
15
15
  mock_git_asset.owner.login = 'mock_username'
16
16
  mock_git_asset.html_url = 'mock/html_url'
17
17
  mock_git_asset.ssh_url = 'mock/ssh_url'
18
+ mock_git_asset.language = 'Python'
18
19
 
19
20
  return mock_git_asset
@@ -306,6 +306,10 @@ def test_initialize_project(mock_make_dirs, mock_dir_exist, mock_logger):
306
306
  {'users': 'justintime50', 'clone': True, 'include': 'mock-repo', 'exclude': 'another-mock-repo'},
307
307
  'The include and exclude flags are mutually exclusive. Only one can be used on each run.',
308
308
  ),
309
+ (
310
+ {'users': 'justintime50', 'clone': True, 'include': 'mock-repo', 'languages': 'python'},
311
+ 'The include and exclude flags cannot be used with the languages flag.',
312
+ ),
309
313
  ],
310
314
  )
311
315
  @patch('github_archive.archive.Github.get_user')
@@ -1,3 +1,4 @@
1
+ import copy
1
2
  import subprocess
2
3
  from unittest.mock import (
3
4
  MagicMock,
@@ -51,7 +52,9 @@ def test_iterate_repos_matching_authed_username(mock_archive_repo, mock_github_i
51
52
  @patch('github_archive.repos._archive_repo')
52
53
  def test_iterate_repos_include_list(mock_archive_repo, mock_github_instance, mock_git_asset):
53
54
  """Tests that we iterate repos that are on the include list."""
54
- repos = [mock_git_asset]
55
+ mock_non_include_asset = copy.deepcopy(mock_git_asset)
56
+ mock_non_include_asset.name = 'not-the-name'
57
+ repos = [mock_git_asset, mock_non_include_asset]
55
58
  github_archive = GithubArchive(
56
59
  users='mock_username',
57
60
  include='mock-asset-name',
@@ -59,14 +62,16 @@ def test_iterate_repos_include_list(mock_archive_repo, mock_github_instance, moc
59
62
 
60
63
  iterate_repos_to_archive(github_archive, repos, CLONE_OPERATION)
61
64
 
62
- mock_archive_repo.assert_called_once()
65
+ mock_archive_repo.assert_called_once() # Called once even though there are two, ensure we filtered
63
66
 
64
67
 
65
68
  @patch('github_archive.archive.Github')
66
69
  @patch('github_archive.repos._archive_repo')
67
70
  def test_iterate_repos_exclude_list(mock_archive_repo, mock_github_instance, mock_git_asset):
68
71
  """Tests that we do not iterate repos that are on the exclude list."""
69
- repos = [mock_git_asset]
72
+ mock_non_exclude_asset = copy.deepcopy(mock_git_asset)
73
+ mock_non_exclude_asset.name = 'not-the-name'
74
+ repos = [mock_git_asset, mock_non_exclude_asset]
70
75
  github_archive = GithubArchive(
71
76
  users='mock_username',
72
77
  exclude='mock-asset-name',
@@ -74,7 +79,24 @@ def test_iterate_repos_exclude_list(mock_archive_repo, mock_github_instance, moc
74
79
 
75
80
  iterate_repos_to_archive(github_archive, repos, CLONE_OPERATION)
76
81
 
77
- mock_archive_repo.assert_not_called()
82
+ mock_archive_repo.assert_called_once() # Called once even though there are two, ensure we filtered
83
+
84
+
85
+ @patch('github_archive.archive.Github')
86
+ @patch('github_archive.repos._archive_repo')
87
+ def test_iterate_repos_languages_list(mock_archive_repo, mock_github_instance, mock_git_asset):
88
+ """Tests that we iterate repos that are one of the languages in the list."""
89
+ mock_non_language_asset = copy.deepcopy(mock_git_asset)
90
+ mock_non_language_asset.language = 'Go'
91
+ repos = [mock_git_asset, mock_non_language_asset]
92
+ github_archive = GithubArchive(
93
+ users='mock_username',
94
+ languages='python',
95
+ )
96
+
97
+ iterate_repos_to_archive(github_archive, repos, CLONE_OPERATION)
98
+
99
+ mock_archive_repo.assert_called_once() # Called once even though there are two, ensure we filtered
78
100
 
79
101
 
80
102
  @patch('logging.Logger.info')
@@ -157,10 +179,14 @@ def test_archive_repo_called_process_error(mock_logger, mock_subprocess, mock_gi
157
179
  mock_logger.assert_called_once()
158
180
 
159
181
 
182
+ @patch('github_archive.archive.Github')
160
183
  @patch('github_archive.repos._fork_repo')
161
- def test_iterate_repos_to_fork(mock_fork_repo):
184
+ def test_iterate_repos_to_fork(mock_fork_repo, mock_github_instance):
162
185
  repo = MagicMock(spec=Repository.Repository)
163
- iterate_repos_to_fork([repo])
186
+ github_archive = GithubArchive(
187
+ gists='mock_username',
188
+ )
189
+ iterate_repos_to_fork(github_archive, [repo])
164
190
 
165
191
  mock_fork_repo.assert_called_once()
166
192
 
@@ -1 +0,0 @@
1
- __version__ = "6.2.0"
File without changes
File without changes
File without changes