Compare commits

...

6 Commits

Author SHA1 Message Date
Jose Diaz-Gonzalez
853b7c46a1 Release version 0.39.0 2021-03-18 23:16:04 -04:00
Jose Diaz-Gonzalez
e23d12d490 Merge pull request #173 from gallofeliz/make-compatible-python-call
Try to make compatible code with direct Python call ; reduce the hard link of the code with the cli
2021-03-18 22:51:01 -04:00
Jose Diaz-Gonzalez
f8e1151111 Merge pull request #174 from atorrescogollo/master
Fixed release_name with slash bug
2021-03-18 22:50:21 -04:00
Álvaro Torres Cogollo
664c2a765e Fixed release_name with slash bug 2021-03-03 11:36:44 +01:00
Gallo Feliz
fa7148d38f fix: fix missing INFO logs 2021-02-16 13:25:16 +01:00
Gallo Feliz
480ce3ce2a Try to make compatible code with direct Python call ; reduce the hard link of the code with the cli 2021-02-16 13:13:51 +01:00
4 changed files with 54 additions and 28 deletions

View File

@@ -1,10 +1,32 @@
Changelog Changelog
========= =========
0.38.0 (2021-02-13) 0.39.0 (2021-03-18)
------------------- -------------------
------------ ------------
Fix
~~~
- Fix missing INFO logs. [Gallo Feliz]
Other
~~~~~
- Merge pull request #173 from gallofeliz/make-compatible-python-call.
[Jose Diaz-Gonzalez]
Try to make compatible code with direct Python call ; reduce the hard link of the code with the cli
- Try to make compatible code with direct Python call ; reduce the hard
link of the code with the cli. [Gallo Feliz]
- Merge pull request #174 from atorrescogollo/master. [Jose Diaz-
Gonzalez]
Fixed release_name with slash bug
- Fixed release_name with slash bug. [Álvaro Torres Cogollo]
0.38.0 (2021-02-13)
-------------------
Fix Fix
~~~ ~~~
- Always clone with OAuth token when provided. [Samantha Baldwin] - Always clone with OAuth token when provided. [Samantha Baldwin]
@@ -16,6 +38,7 @@ Fix
Other Other
~~~~~ ~~~~~
- Release version 0.38.0. [Jose Diaz-Gonzalez]
- Merge pull request #172 from samanthaq/always-use-oauth-when-provided. - Merge pull request #172 from samanthaq/always-use-oauth-when-provided.
[Jose Diaz-Gonzalez] [Jose Diaz-Gonzalez]

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
import os import os, sys, logging
from github_backup.github_backup import ( from github_backup.github_backup import (
backup_account, backup_account,
@@ -9,11 +9,17 @@ from github_backup.github_backup import (
filter_repositories, filter_repositories,
get_authenticated_user, get_authenticated_user,
log_info, log_info,
log_warning,
mkdir_p, mkdir_p,
parse_args, parse_args,
retrieve_repositories, retrieve_repositories,
) )
logging.basicConfig(
format='%(asctime)s.%(msecs)03d: %(message)s',
datefmt='%Y-%m-%dT%H:%M:%S',
level=logging.INFO
)
def main(): def main():
args = parse_args() args = parse_args()
@@ -39,4 +45,8 @@ def main():
if __name__ == '__main__': if __name__ == '__main__':
main() try:
main()
except Exception as e:
log_warning(str(e))
sys.exit(1)

View File

@@ -1 +1 @@
__version__ = '0.38.0' __version__ = '0.39.0'

View File

@@ -17,6 +17,7 @@ import re
import select import select
import subprocess import subprocess
import sys import sys
import logging
import time import time
import platform import platform
from urllib.parse import urlparse from urllib.parse import urlparse
@@ -40,15 +41,6 @@ FNULL = open(os.devnull, 'w')
def _get_log_date(): def _get_log_date():
return datetime.datetime.isoformat(datetime.datetime.now()) return datetime.datetime.isoformat(datetime.datetime.now())
def log_error(message):
"""
Log message (str) or messages (List[str]) to stderr and exit with status 1
"""
log_warning(message)
sys.exit(1)
def log_info(message): def log_info(message):
""" """
Log message (str) or messages (List[str]) to stdout Log message (str) or messages (List[str]) to stdout
@@ -57,7 +49,7 @@ def log_info(message):
message = [message] message = [message]
for msg in message: for msg in message:
sys.stdout.write("{0}: {1}\n".format(_get_log_date(), msg)) logging.info(msg)
def log_warning(message): def log_warning(message):
@@ -68,7 +60,7 @@ def log_warning(message):
message = [message] message = [message]
for msg in message: for msg in message:
sys.stderr.write("{0}: {1}\n".format(_get_log_date(), msg)) logging.warning(msg)
def logging_subprocess(popenargs, def logging_subprocess(popenargs,
@@ -140,7 +132,7 @@ def mask_password(url, secret='*****'):
return url.replace(parsed.password, secret) return url.replace(parsed.password, secret)
def parse_args(): def parse_args(args = None):
parser = argparse.ArgumentParser(description='Backup a github account') parser = argparse.ArgumentParser(description='Backup a github account')
parser.add_argument('user', parser.add_argument('user',
metavar='USER', metavar='USER',
@@ -331,7 +323,7 @@ def parse_args():
type=float, type=float,
default=30.0, default=30.0,
help='wait this amount of seconds when API request throttling is active (default: 30.0, requires --throttle-limit to be set)') help='wait this amount of seconds when API request throttling is active (default: 30.0, requires --throttle-limit to be set)')
return parser.parse_args() return parser.parse_args(args)
def get_auth(args, encode=True, for_git_cli=False): def get_auth(args, encode=True, for_git_cli=False):
@@ -339,10 +331,10 @@ def get_auth(args, encode=True, for_git_cli=False):
if args.osx_keychain_item_name: if args.osx_keychain_item_name:
if not args.osx_keychain_item_account: if not args.osx_keychain_item_account:
log_error('You must specify both name and account fields for osx keychain password items') raise Exception('You must specify both name and account fields for osx keychain password items')
else: else:
if platform.system() != 'Darwin': if platform.system() != 'Darwin':
log_error("Keychain arguments are only supported on Mac OSX") raise Exception("Keychain arguments are only supported on Mac OSX")
try: try:
with open(os.devnull, 'w') as devnull: with open(os.devnull, 'w') as devnull:
token = (subprocess.check_output([ token = (subprocess.check_output([
@@ -353,9 +345,9 @@ def get_auth(args, encode=True, for_git_cli=False):
token = token.decode('utf-8') token = token.decode('utf-8')
auth = token + ':' + 'x-oauth-basic' auth = token + ':' + 'x-oauth-basic'
except subprocess.SubprocessError: except subprocess.SubprocessError:
log_error('No password item matching the provided name and account could be found in the osx keychain.') raise Exception('No password item matching the provided name and account could be found in the osx keychain.')
elif args.osx_keychain_item_account: elif args.osx_keychain_item_account:
log_error('You must specify both name and account fields for osx keychain password items') raise Exception('You must specify both name and account fields for osx keychain password items')
elif args.token: elif args.token:
_path_specifier = 'file://' _path_specifier = 'file://'
if args.token.startswith(_path_specifier): if args.token.startswith(_path_specifier):
@@ -377,7 +369,7 @@ def get_auth(args, encode=True, for_git_cli=False):
password = urlquote(args.password) password = urlquote(args.password)
auth = args.username + ':' + password auth = args.username + ':' + password
elif args.password: elif args.password:
log_error('You must specify a username for basic auth') raise Exception('You must specify a username for basic auth')
if not auth: if not auth:
return None return None
@@ -466,7 +458,7 @@ def retrieve_data_gen(args, template, query_args=None, single_request=False):
if status_code != 200: if status_code != 200:
template = 'API request returned HTTP {0}: {1}' template = 'API request returned HTTP {0}: {1}'
errors.append(template.format(status_code, r.reason)) errors.append(template.format(status_code, r.reason))
log_error(errors) raise Exception(', '.join(errors))
response = json.loads(r.read().decode('utf-8')) response = json.loads(r.read().decode('utf-8'))
if len(errors) == 0: if len(errors) == 0:
@@ -479,7 +471,7 @@ def retrieve_data_gen(args, template, query_args=None, single_request=False):
yield response yield response
if len(errors) > 0: if len(errors) > 0:
log_error(errors) raise Exception(', '.join(errors))
if single_request: if single_request:
break break
@@ -582,7 +574,7 @@ def _request_url_error(template, retry_timeout):
if retry_timeout >= 0: if retry_timeout >= 0:
return True return True
log_error('{} timed out to much, skipping!') raise Exception('{} timed out to much, skipping!')
return False return False
@@ -640,7 +632,7 @@ def get_authenticated_user(args):
def check_git_lfs_install(): def check_git_lfs_install():
exit_code = subprocess.call(['git', 'lfs', 'version']) exit_code = subprocess.call(['git', 'lfs', 'version'])
if exit_code != 0: if exit_code != 0:
log_error('The argument --lfs requires you to have Git LFS installed.\nYou can get it from https://git-lfs.github.com.') raise Exception('The argument --lfs requires you to have Git LFS installed.\nYou can get it from https://git-lfs.github.com.')
def retrieve_repositories(args, authenticated_user): def retrieve_repositories(args, authenticated_user):
@@ -1009,7 +1001,8 @@ def backup_releases(args, repo_cwd, repository, repos_template, include_assets=F
log_info('Saving {0} releases to disk'.format(len(releases))) log_info('Saving {0} releases to disk'.format(len(releases)))
for release in releases: for release in releases:
release_name = release['tag_name'] release_name = release['tag_name']
output_filepath = os.path.join(release_cwd, '{0}.json'.format(release_name)) release_name_safe = release_name.replace('/', '__')
output_filepath = os.path.join(release_cwd, '{0}.json'.format(release_name_safe))
with codecs.open(output_filepath, 'w+', encoding='utf-8') as f: with codecs.open(output_filepath, 'w+', encoding='utf-8') as f:
json_dump(release, f) json_dump(release, f)
@@ -1017,7 +1010,7 @@ def backup_releases(args, repo_cwd, repository, repos_template, include_assets=F
assets = retrieve_data(args, release['assets_url']) assets = retrieve_data(args, release['assets_url'])
if len(assets) > 0: if len(assets) > 0:
# give release asset files somewhere to live & download them (not including source archives) # give release asset files somewhere to live & download them (not including source archives)
release_assets_cwd = os.path.join(release_cwd, release_name) release_assets_cwd = os.path.join(release_cwd, release_name_safe)
mkdir_p(release_assets_cwd) mkdir_p(release_assets_cwd)
for asset in assets: for asset in assets:
download_file(asset['url'], os.path.join(release_assets_cwd, asset['name']), get_auth(args)) download_file(asset['url'], os.path.join(release_assets_cwd, asset['name']), get_auth(args))